gloomberb 0.18.3 → 0.18.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (886) hide show
  1. package/README.md +8 -8
  2. package/README.zh-CN.md +11 -11
  3. package/bin/{gloomberb → gloom} +3 -1
  4. package/package.json +6 -2
  5. package/src/account/checkout-handoff.tsx +225 -0
  6. package/src/account/device-signin-dialog.tsx +2 -2
  7. package/src/account/device-signin.ts +2 -2
  8. package/src/account/upgrade-dialog.tsx +1 -1
  9. package/src/api-client/askg.ts +2 -2
  10. package/src/api-client/auth.ts +2 -2
  11. package/src/api-client/central-bank-rates.ts +6 -0
  12. package/src/api-client/collections.ts +5 -1
  13. package/src/api-client/cot.ts +2 -0
  14. package/src/api-client/crypto-etf-flows.ts +37 -0
  15. package/src/api-client/crypto-markets.ts +60 -0
  16. package/src/api-client/data.ts +84 -5
  17. package/src/api-client/doe.ts +15 -0
  18. package/src/api-client/equity-screener.ts +28 -0
  19. package/src/api-client/exchange-announcements.ts +38 -0
  20. package/src/api-client/fund-facts.ts +39 -0
  21. package/src/api-client/futures-curve.ts +9 -1
  22. package/src/api-client/hiring.ts +301 -0
  23. package/src/api-client/index.ts +22 -5
  24. package/src/api-client/market-discovery.ts +14 -0
  25. package/src/api-client/members.ts +6 -0
  26. package/src/api-client/mna.ts +6 -0
  27. package/src/api-client/paths.ts +18 -1
  28. package/src/api-client/request.ts +21 -4
  29. package/src/api-client/short-side-publications.ts +37 -0
  30. package/src/api-client/socket.ts +64 -4
  31. package/src/api-client/swap-curve.ts +35 -0
  32. package/src/api-client/themes.ts +7 -1
  33. package/src/api-client/types.ts +90 -2
  34. package/src/app/pane-runtime/plugin-bindings.ts +9 -2
  35. package/src/app/runtime/desktop-deeplink.ts +5 -5
  36. package/src/app/runtime/plugin-bindings.ts +2 -2
  37. package/src/app/runtime/startup.ts +13 -0
  38. package/src/app/star-prompt/status-line.tsx +2 -2
  39. package/src/architecture/core-builtin-allowlist.json +5 -2
  40. package/src/architecture/ui-literals-allowlist.json +3 -3
  41. package/src/architecture/ui-tokens-allowlist.json +1 -1
  42. package/src/brokers/broker-portfolio-sync.ts +37 -0
  43. package/src/brokers/directory.ts +11 -0
  44. package/src/brokers/logos.ts +3 -1
  45. package/src/brokers/signed-in/adapter.ts +304 -26
  46. package/src/brokers/signed-in/client.ts +14 -2
  47. package/src/brokers/signed-in/connect.ts +10 -2
  48. package/src/brokers/sync-broker-instance.ts +9 -1
  49. package/src/capabilities/chart-series.ts +22 -6
  50. package/src/cli/bank-section.ts +1 -1
  51. package/src/cli/base-converter.ts +23 -14
  52. package/src/cli/central-bank-events.ts +1 -1
  53. package/src/cli/command-options.ts +59 -4
  54. package/src/cli/commands/api.ts +9 -6
  55. package/src/cli/commands/broker.ts +2 -2
  56. package/src/cli/commands/command-utils.ts +2 -2
  57. package/src/cli/commands/crypto-hints.ts +7 -20
  58. package/src/cli/commands/fred-series.ts +4 -2
  59. package/src/cli/commands/keybindings.ts +2 -2
  60. package/src/cli/commands/market.ts +1117 -264
  61. package/src/cli/commands/news-hints.ts +2 -2
  62. package/src/cli/commands/news-search.ts +59 -6
  63. package/src/cli/commands/options-leaps.ts +41 -26
  64. package/src/cli/commands/overview.ts +121 -48
  65. package/src/cli/commands/plugins.ts +9 -9
  66. package/src/cli/commands/remote.ts +13 -10
  67. package/src/cli/commands/search.ts +64 -44
  68. package/src/cli/commands/system.ts +27 -19
  69. package/src/cli/commands/themes.ts +1 -1
  70. package/src/cli/commands/ticker.ts +192 -47
  71. package/src/cli/context.ts +3 -2
  72. package/src/cli/desktop-pane-shot-view.ts +2 -2
  73. package/src/cli/desktop-pane-shot.ts +1 -1
  74. package/src/cli/earnings-calendar.ts +4 -4
  75. package/src/cli/entry.ts +18 -1
  76. package/src/cli/errors.ts +20 -2
  77. package/src/cli/exit-codes.ts +1 -1
  78. package/src/cli/export-source.ts +10 -4
  79. package/src/cli/freshness.ts +2 -8
  80. package/src/cli/fx-forward.ts +130 -0
  81. package/src/cli/fx-pair.ts +10 -9
  82. package/src/cli/glossary.ts +64 -20
  83. package/src/cli/help.ts +19 -13
  84. package/src/cli/history-export.ts +126 -0
  85. package/src/cli/history-rows.ts +196 -43
  86. package/src/cli/index-roots.ts +5 -45
  87. package/src/cli/index.ts +24 -18
  88. package/src/cli/known-gaps.ts +118 -25
  89. package/src/cli/listing-arg.ts +300 -41
  90. package/src/cli/name-entries.ts +30 -18
  91. package/src/cli/native-smoke.ts +2 -0
  92. package/src/cli/not-a-ticker.ts +19 -9
  93. package/src/cli/opentui-libc.ts +5 -0
  94. package/src/cli/options.ts +12 -0
  95. package/src/cli/pane-functions/capabilities.ts +75 -20
  96. package/src/cli/pane-functions/catalog.ts +24 -23
  97. package/src/cli/pane-functions/discovery.ts +1 -1
  98. package/src/cli/pane-functions/dom.ts +10 -7
  99. package/src/cli/pane-functions/financial-ratio-shot.ts +2 -2
  100. package/src/cli/pane-functions/freshness.ts +174 -23
  101. package/src/cli/pane-functions/function-help.ts +66 -27
  102. package/src/cli/pane-functions/headless.ts +24 -11
  103. package/src/cli/pane-functions/index.ts +18 -16
  104. package/src/cli/pane-functions/options.ts +22 -2
  105. package/src/cli/pane-functions/report-notices.ts +12 -4
  106. package/src/cli/pane-functions/report.ts +5 -5
  107. package/src/cli/pane-functions/resolver.ts +47 -10
  108. package/src/cli/pane-functions/screenshot-assessment.ts +322 -0
  109. package/src/cli/pane-functions/screenshot-bridge.ts +152 -0
  110. package/src/cli/pane-functions/screenshot-chart-evidence.ts +396 -0
  111. package/src/cli/pane-functions/screenshot-data-evidence.ts +383 -0
  112. package/src/cli/pane-functions/screenshot-evidence.ts +1 -1
  113. package/src/cli/pane-functions/screenshot-payload.ts +453 -0
  114. package/src/cli/pane-functions/screenshot-render.ts +316 -0
  115. package/src/cli/pane-functions/screenshot-types.ts +162 -0
  116. package/src/cli/pane-functions/shot-options.ts +8 -3
  117. package/src/cli/peso-dollar-rates.ts +79 -0
  118. package/src/cli/quote-answer.ts +38 -3
  119. package/src/cli/report-tables.ts +61 -16
  120. package/src/cli/restore-plugins.ts +29 -14
  121. package/src/cli/result.ts +111 -22
  122. package/src/cli/series-search.ts +5 -5
  123. package/src/cli/statement-filings.ts +19 -0
  124. package/src/cli/suffixed-listing-rows.ts +49 -0
  125. package/src/cli/symbol-args.ts +50 -15
  126. package/src/cli/symbol-cells.ts +120 -0
  127. package/src/cli/symbol-list.ts +198 -68
  128. package/src/cli/symbol-rows.ts +131 -25
  129. package/src/cli/ticker-resolution.ts +108 -11
  130. package/src/cli/treasury-yields.ts +5 -5
  131. package/src/cli/types.ts +2 -0
  132. package/src/cli/uncovered-instrument.ts +3 -3
  133. package/src/cli/unknown-command.ts +6 -6
  134. package/src/components/chart/composite/chart-layout.ts +131 -0
  135. package/src/components/chart/composite/composite-chart.tsx +373 -16
  136. package/src/components/chart/composite/interactions.ts +7 -2
  137. package/src/components/chart/composite/legend.tsx +75 -3
  138. package/src/components/chart/composite/levels.ts +5 -0
  139. package/src/components/chart/composite/panel-gestures.ts +41 -0
  140. package/src/components/chart/composite/panel-labels.ts +2 -1
  141. package/src/components/chart/composite/panel-surface.tsx +305 -11
  142. package/src/components/chart/composite/price-axis-labels.tsx +27 -3
  143. package/src/components/chart/composite/rasterizer.ts +44 -19
  144. package/src/components/chart/composite/scene.ts +16 -4
  145. package/src/components/chart/composite/text-renderer.ts +48 -21
  146. package/src/components/chart/composite/toolbar.tsx +52 -5
  147. package/src/components/chart/composite/types.ts +13 -0
  148. package/src/components/chart/composite/use-composite-chart-keyboard.ts +120 -13
  149. package/src/components/chart/composite/use-composite-value-scales.ts +44 -0
  150. package/src/components/chart/composite/use-composite-viewport.ts +12 -3
  151. package/src/components/chart/composite/value-scale.ts +149 -0
  152. package/src/components/chart/composite/volume-profile-paint.ts +6 -3
  153. package/src/components/chart/core/pointer.ts +2 -0
  154. package/src/components/chart-table/index.ts +2 -0
  155. package/src/components/chart-table/read.tsx +74 -0
  156. package/src/components/command-bar/commands/collection-list.ts +41 -19
  157. package/src/components/command-bar/commands/collection.ts +9 -3
  158. package/src/components/command-bar/commands/direct/index.ts +1 -1
  159. package/src/components/command-bar/commands/direct/runtime.ts +3 -2
  160. package/src/components/command-bar/pane-templates/items.ts +59 -6
  161. package/src/components/command-bar/pane-templates/workflow.ts +10 -1
  162. package/src/components/command-bar/routes/root/plugin-install.ts +1 -1
  163. package/src/components/command-bar/routes/root/provider-search.ts +42 -11
  164. package/src/components/command-bar/routes/root/results.ts +18 -4
  165. package/src/components/command-bar/routes/root/runtime.ts +15 -3
  166. package/src/components/command-bar/routes/root/search-providers.ts +25 -2
  167. package/src/components/command-bar/routes/root/selection.ts +6 -1
  168. package/src/components/command-bar/routes/root/shortcut-feedback.ts +4 -1
  169. package/src/components/command-bar/routes/root/shortcuts.ts +30 -3
  170. package/src/components/command-bar/routes/ticker-search/results.ts +73 -4
  171. package/src/components/command-bar/selection-runtime.ts +50 -10
  172. package/src/components/command-bar/surface/index.tsx +24 -2
  173. package/src/components/command-bar/view-model.ts +7 -0
  174. package/src/components/command-bar/workflow/broker.ts +2 -2
  175. package/src/components/command-bar/workflow/collection-actions.ts +46 -7
  176. package/src/components/command-bar/workflow/collection-ticker.ts +32 -4
  177. package/src/components/command-bar/workflow/fields.ts +8 -2
  178. package/src/components/command-bar/workflow/ops.ts +18 -4
  179. package/src/components/command-bar/workflow/portfolio-position.ts +53 -4
  180. package/src/components/command-bar/workflow/submit.ts +3 -2
  181. package/src/components/command-bar/workflow/tickers.ts +5 -1
  182. package/src/components/company-logo.tsx +39 -0
  183. package/src/components/data-table/sections.ts +4 -2
  184. package/src/components/form-modal/confirm.tsx +2 -1
  185. package/src/components/form-modal/request.ts +5 -0
  186. package/src/components/form-modal/routes.ts +4 -1
  187. package/src/components/index.ts +12 -6
  188. package/src/components/layout/header.tsx +7 -6
  189. package/src/components/layout/market-summary.ts +9 -6
  190. package/src/components/layout/pane/capture-status.ts +1 -1
  191. package/src/components/layout/pane/footer/model.ts +11 -5
  192. package/src/components/layout/shell/chrome.ts +19 -6
  193. package/src/components/layout/shell/index.tsx +2 -1
  194. package/src/components/layout/shell/pane/layers.tsx +19 -1
  195. package/src/components/layout/status-bar.tsx +2 -2
  196. package/src/components/market-board/index.tsx +11 -3
  197. package/src/components/onboarding/onboarding-wizard.tsx +1 -0
  198. package/src/components/onboarding/portfolio-step/broker-setup-panel.tsx +2 -2
  199. package/src/components/onboarding/wizard-broker-sync.ts +4 -1
  200. package/src/components/pane-settings-dialog/desktop.tsx +20 -7
  201. package/src/components/pane-settings-dialog/tui.tsx +17 -9
  202. package/src/components/pane-settings-dialog/value.ts +8 -1
  203. package/src/components/pane-settings-dialog.tsx +44 -13
  204. package/src/components/sign-in-code-panel.tsx +27 -19
  205. package/src/components/ui/column-grid.tsx +48 -4
  206. package/src/components/ui/country-flag-art.tsx +180 -0
  207. package/src/components/ui/country-flag.tsx +118 -12
  208. package/src/components/ui/data-table/opentui/index.tsx +61 -2
  209. package/src/components/ui/data-table/opentui/model.ts +109 -2
  210. package/src/components/ui/data-table/types.ts +1 -1
  211. package/src/components/ui/display.tsx +5 -1
  212. package/src/components/ui/index.ts +3 -1
  213. package/src/components/ui/logo-mark.tsx +11 -2
  214. package/src/components/ui/query-bar.tsx +1 -1
  215. package/src/components/ui/row-notes.ts +79 -0
  216. package/src/core/state/app/layout.ts +4 -4
  217. package/src/data/cached-query.ts +8 -1
  218. package/src/data/config/chart-settings.ts +3 -3
  219. package/src/data/config/home.ts +10 -2
  220. package/src/data/config/layout.ts +4 -1
  221. package/src/data/config/store/node.ts +4 -0
  222. package/src/data/config/store/normalize.ts +13 -3
  223. package/src/data/config/store/portfolio-as-of-column.ts +2 -2
  224. package/src/data/json-storage.ts +2 -0
  225. package/src/data/saved-copies.ts +84 -0
  226. package/src/docs/snapshot.json +65 -32
  227. package/src/i18n/es.ts +29 -12
  228. package/src/i18n/ja.ts +29 -12
  229. package/src/i18n/ko.ts +29 -12
  230. package/src/i18n/zh-cn.ts +29 -12
  231. package/src/i18n/zh-tw.ts +29 -12
  232. package/src/layout/desks.ts +1 -1
  233. package/src/layout/launch-layout.ts +1 -1
  234. package/src/layout/pane-manager/floating-actions.ts +5 -3
  235. package/src/layout/pane-manager/floating.ts +43 -1
  236. package/src/layout/pane-manager/index.ts +2 -0
  237. package/src/layout/selected-ticker.ts +74 -0
  238. package/src/market-data/depositary-pair.ts +251 -0
  239. package/src/market-data/futures-board.ts +1 -1
  240. package/src/market-data/futures-contract.ts +124 -40
  241. package/src/market-data/fx-closes.ts +17 -2
  242. package/src/market-data/hooks.tsx +19 -11
  243. package/src/market-data/market/change-basis.ts +49 -7
  244. package/src/market-data/market/freshness.ts +34 -5
  245. package/src/market-data/market/period-return.ts +163 -0
  246. package/src/market-data/market/trading-sessions.ts +13 -0
  247. package/src/market-data/market/year-to-date.ts +8 -13
  248. package/src/market-data/performance.ts +20 -14
  249. package/src/market-data/perpetual-premium.ts +32 -0
  250. package/src/market-data/published-apac-sessions.ts +2 -1
  251. package/src/market-data/published-futures-sessions.ts +69 -0
  252. package/src/market-data/quotes/contributions.ts +5 -1
  253. package/src/market-data/quotes/freshness.ts +42 -0
  254. package/src/market-data/quotes/intraday-bar.ts +37 -0
  255. package/src/market-data/quotes/regular-session-valuation.ts +13 -8
  256. package/src/market-data/quotes/resolution.ts +4 -2
  257. package/src/market-data/tax-equivalent.ts +1 -1
  258. package/src/market-data/ticker-price-returns.ts +3 -1
  259. package/src/news/aggregator.ts +5 -1
  260. package/src/news/news-model.ts +4 -0
  261. package/src/news/types.ts +11 -0
  262. package/src/notifications/app-notifier.ts +1 -1
  263. package/src/plugins/auto-update.ts +2 -2
  264. package/src/plugins/builtin/account-management/index.tsx +1 -0
  265. package/src/plugins/builtin/account-management/pane.tsx +9 -8
  266. package/src/plugins/builtin/alerts/alert-engine.ts +29 -19
  267. package/src/plugins/builtin/alerts/calendar-events.ts +378 -0
  268. package/src/plugins/builtin/alerts/cli.ts +485 -76
  269. package/src/plugins/builtin/alerts/command.ts +5 -10
  270. package/src/plugins/builtin/alerts/event-rows.ts +9 -5
  271. package/src/plugins/builtin/alerts/events-pane.tsx +71 -56
  272. package/src/plugins/builtin/alerts/events.ts +107 -5
  273. package/src/plugins/builtin/alerts/fired-log.ts +78 -0
  274. package/src/plugins/builtin/alerts/format.ts +2 -1
  275. package/src/plugins/builtin/alerts/headless.ts +100 -39
  276. package/src/plugins/builtin/alerts/history-pane.tsx +105 -62
  277. package/src/plugins/builtin/alerts/history-rows.ts +89 -0
  278. package/src/plugins/builtin/alerts/index.tsx +45 -18
  279. package/src/plugins/builtin/alerts/iv-level.ts +365 -0
  280. package/src/plugins/builtin/alerts/levels.ts +3 -3
  281. package/src/plugins/builtin/alerts/pane.tsx +97 -29
  282. package/src/plugins/builtin/alerts/price.ts +35 -0
  283. package/src/plugins/builtin/alerts/quotes.ts +24 -0
  284. package/src/plugins/builtin/alerts/research-builder.ts +84 -11
  285. package/src/plugins/builtin/alerts/research-rules.ts +76 -3
  286. package/src/plugins/builtin/alerts/scheduled-check.ts +206 -32
  287. package/src/plugins/builtin/alerts/scheduled-sources.ts +26 -3
  288. package/src/plugins/builtin/alerts/scheduled.ts +188 -29
  289. package/src/plugins/builtin/alerts/storage.ts +13 -10
  290. package/src/plugins/builtin/alerts/targets.ts +12 -3
  291. package/src/plugins/builtin/analytics/index.tsx +8 -2
  292. package/src/plugins/builtin/analytics/metrics.ts +1 -1
  293. package/src/plugins/builtin/analytics/risk-book.ts +215 -0
  294. package/src/plugins/builtin/analytics/risk-client.ts +13 -6
  295. package/src/plugins/builtin/analytics/risk-headless.ts +55 -21
  296. package/src/plugins/builtin/analytics/risk-math.ts +6 -3
  297. package/src/plugins/builtin/analytics/risk-model.ts +297 -104
  298. package/src/plugins/builtin/analytics/risk-options.ts +17 -2
  299. package/src/plugins/builtin/analytics/risk-pane.tsx +97 -36
  300. package/src/plugins/builtin/attention/pane.tsx +6 -2
  301. package/src/plugins/builtin/awards/headless.ts +7 -3
  302. package/src/plugins/builtin/awards/model.ts +18 -0
  303. package/src/plugins/builtin/awards/pane.tsx +6 -3
  304. package/src/plugins/builtin/backtest/headless.ts +3 -3
  305. package/src/plugins/builtin/backtest/rules.ts +41 -5
  306. package/src/plugins/builtin/broker-manager/add-flow.tsx +12 -7
  307. package/src/plugins/builtin/broker-manager/detail.tsx +47 -19
  308. package/src/plugins/builtin/broker-manager/footer.ts +27 -11
  309. package/src/plugins/builtin/broker-manager/index.tsx +21 -12
  310. package/src/plugins/builtin/broker-manager/keyboard.ts +1 -1
  311. package/src/plugins/builtin/broker-manager/model.ts +12 -2
  312. package/src/plugins/builtin/broker-manager/pane-actions.tsx +183 -57
  313. package/src/plugins/builtin/broker-manager/table.ts +28 -12
  314. package/src/plugins/builtin/broker-trading/account-picker.tsx +2 -1
  315. package/src/plugins/builtin/broker-trading/chart-levels.ts +82 -13
  316. package/src/plugins/builtin/broker-trading/controller.ts +45 -13
  317. package/src/plugins/builtin/broker-trading/dock.tsx +22 -4
  318. package/src/plugins/builtin/broker-trading/headless.ts +2 -1
  319. package/src/plugins/builtin/broker-trading/index.tsx +7 -1
  320. package/src/plugins/builtin/broker-trading/linked-orders.ts +148 -0
  321. package/src/plugins/builtin/broker-trading/order-feed.ts +75 -7
  322. package/src/plugins/builtin/broker-trading/orders.tsx +109 -31
  323. package/src/plugins/builtin/broker-trading/overview-orders.tsx +9 -3
  324. package/src/plugins/builtin/broker-trading/pane-model.ts +30 -2
  325. package/src/plugins/builtin/broker-trading/pane.tsx +110 -23
  326. package/src/plugins/builtin/broker-trading/ticket-parts.tsx +36 -7
  327. package/src/plugins/builtin/broker-trading/ticket.tsx +112 -31
  328. package/src/plugins/builtin/buildout/cells.tsx +4 -0
  329. package/src/plugins/builtin/buildout/detail/index.tsx +5 -1
  330. package/src/plugins/builtin/buildout/detail/ui.tsx +7 -4
  331. package/src/plugins/builtin/buildout/pane/index.tsx +25 -12
  332. package/src/plugins/builtin/buildout/pane/status.tsx +0 -4
  333. package/src/plugins/builtin/builtin-plugin-meta.ts +1 -1
  334. package/src/plugins/builtin/catalysts/detail.tsx +3 -2
  335. package/src/plugins/builtin/catalysts/index.tsx +1 -1
  336. package/src/plugins/builtin/catalysts/model.ts +49 -4
  337. package/src/plugins/builtin/catalysts/pane.tsx +6 -8
  338. package/src/plugins/builtin/central-bank-rates/client.ts +5 -0
  339. package/src/plugins/builtin/central-bank-rates/headless.ts +36 -10
  340. package/src/plugins/builtin/central-bank-rates/model.ts +33 -8
  341. package/src/plugins/builtin/changelog/index.tsx +1 -0
  342. package/src/plugins/builtin/chart-composer/catalog-inventory.ts +1 -0
  343. package/src/plugins/builtin/chart-composer/chart-spec-edit.ts +2 -1
  344. package/src/plugins/builtin/chart-composer/chart-spec.ts +7 -0
  345. package/src/plugins/builtin/chart-composer/cli-options.ts +2 -5
  346. package/src/plugins/builtin/chart-composer/data-catalog-pane.tsx +2 -1
  347. package/src/plugins/builtin/chart-composer/editor/controller.ts +2 -0
  348. package/src/plugins/builtin/chart-composer/editor.tsx +4 -1
  349. package/src/plugins/builtin/chart-composer/headless-schema.ts +28 -26
  350. package/src/plugins/builtin/chart-composer/headless.ts +253 -35
  351. package/src/plugins/builtin/chart-composer/index.tsx +12 -2
  352. package/src/plugins/builtin/chart-composer/leverage-overlay.ts +142 -0
  353. package/src/plugins/builtin/chart-composer/pane.tsx +127 -28
  354. package/src/plugins/builtin/chart-composer/series-catalog.ts +1 -0
  355. package/src/plugins/builtin/chart-composer/series-expression.ts +65 -6
  356. package/src/plugins/builtin/chart-composer/session-history.ts +15 -21
  357. package/src/plugins/builtin/chart-composer/session-range.ts +4 -2
  358. package/src/plugins/builtin/chart-composer/settings.ts +31 -19
  359. package/src/plugins/builtin/chart-composer/use-series-catalog.ts +5 -6
  360. package/src/plugins/builtin/chart-composer/viewport-labels.ts +18 -8
  361. package/src/plugins/builtin/chat/attachments/model.ts +3 -1
  362. package/src/plugins/builtin/chat/content/index.tsx +1 -1
  363. package/src/plugins/builtin/chat/pane-links/open.ts +1 -1
  364. package/src/plugins/builtin/chat/people.ts +1 -1
  365. package/src/plugins/builtin/clinical-trials/client.ts +5 -2
  366. package/src/plugins/builtin/clinical-trials/model.ts +13 -4
  367. package/src/plugins/builtin/clinical-trials/pane.tsx +32 -12
  368. package/src/plugins/builtin/clinical-trials/ticker-sponsor.ts +17 -0
  369. package/src/plugins/builtin/cloud/askg/controller.ts +1 -1
  370. package/src/plugins/builtin/cloud/askg/lock-note.ts +1 -1
  371. package/src/plugins/builtin/cloud/askg/tool-display.ts +1 -1
  372. package/src/plugins/builtin/cloud/auth-commands.ts +3 -3
  373. package/src/plugins/builtin/cloud/team/pane-sections.tsx +105 -47
  374. package/src/plugins/builtin/cloud/team/pane-ui.tsx +42 -4
  375. package/src/plugins/builtin/cloud/team/pane.tsx +204 -64
  376. package/src/plugins/builtin/cloud/thesis/store.ts +45 -22
  377. package/src/plugins/builtin/cloud-tweets/registration.ts +1 -0
  378. package/src/plugins/builtin/commodities-energy/index.tsx +29 -2
  379. package/src/plugins/builtin/commodities-energy/view-state.ts +2 -0
  380. package/src/plugins/builtin/commodity-balances/pane.tsx +11 -4
  381. package/src/plugins/builtin/company-attention/app-rank.tsx +7 -5
  382. package/src/plugins/builtin/company-attention/building-model.ts +222 -0
  383. package/src/plugins/builtin/company-attention/building.tsx +172 -0
  384. package/src/plugins/builtin/company-attention/client.ts +117 -1
  385. package/src/plugins/builtin/company-attention/evidence.ts +16 -3
  386. package/src/plugins/builtin/company-attention/headless.ts +101 -5
  387. package/src/plugins/builtin/company-attention/index.tsx +6 -3
  388. package/src/plugins/builtin/company-attention/model.ts +33 -7
  389. package/src/plugins/builtin/company-attention/moves-model.ts +253 -0
  390. package/src/plugins/builtin/company-attention/moves.tsx +159 -0
  391. package/src/plugins/builtin/company-attention/pane.tsx +79 -23
  392. package/src/plugins/builtin/company-attention/signals-model.ts +229 -0
  393. package/src/plugins/builtin/company-attention/signals.tsx +160 -0
  394. package/src/plugins/builtin/company-kpis/headless.ts +3 -2
  395. package/src/plugins/builtin/company-kpis/model.ts +2 -2
  396. package/src/plugins/builtin/company-kpis/pane.tsx +1 -1
  397. package/src/plugins/builtin/composite-plugins.ts +2 -1
  398. package/src/plugins/builtin/congress-trades/headless.ts +1 -1
  399. package/src/plugins/builtin/connections/index.ts +1 -0
  400. package/src/plugins/builtin/correlation/headless-schema.ts +3 -2
  401. package/src/plugins/builtin/correlation/headless.ts +5 -3
  402. package/src/plugins/builtin/cot/headless.ts +28 -6
  403. package/src/plugins/builtin/cot/model.ts +12 -0
  404. package/src/plugins/builtin/cot/pane.tsx +3 -2
  405. package/src/plugins/builtin/cpi/headless.ts +5 -1
  406. package/src/plugins/builtin/cpi/pane.tsx +11 -9
  407. package/src/plugins/builtin/credit-boards/model.ts +2 -0
  408. package/src/plugins/builtin/credit-documents/headless.ts +1 -1
  409. package/src/plugins/builtin/crypto-board/client.ts +86 -0
  410. package/src/plugins/builtin/crypto-board/defi-view.tsx +218 -0
  411. package/src/plugins/builtin/crypto-board/defi.ts +239 -0
  412. package/src/plugins/builtin/crypto-board/headless.ts +117 -6
  413. package/src/plugins/builtin/crypto-board/index.tsx +8 -3
  414. package/src/plugins/builtin/crypto-board/model.ts +40 -8
  415. package/src/plugins/builtin/crypto-board/pane.tsx +55 -21
  416. package/src/plugins/builtin/crypto-board/series.ts +19 -1
  417. package/src/plugins/builtin/crypto-etf-flows/client.ts +60 -0
  418. package/src/plugins/builtin/crypto-etf-flows/headless.ts +132 -0
  419. package/src/plugins/builtin/crypto-etf-flows/index.tsx +44 -0
  420. package/src/plugins/builtin/crypto-etf-flows/model.ts +121 -0
  421. package/src/plugins/builtin/crypto-etf-flows/pane.tsx +193 -0
  422. package/src/plugins/builtin/debug/index.tsx +1 -0
  423. package/src/plugins/builtin/dividend-yield/index.tsx +1 -1
  424. package/src/plugins/builtin/docs/index.tsx +1 -1
  425. package/src/plugins/builtin/docs/pane.tsx +2 -2
  426. package/src/plugins/builtin/docs/targets.ts +1 -1
  427. package/src/plugins/builtin/doe/client.ts +5 -1
  428. package/src/plugins/builtin/doe/headless.ts +12 -6
  429. package/src/plugins/builtin/doe/model.ts +43 -6
  430. package/src/plugins/builtin/doe/pane.tsx +18 -11
  431. package/src/plugins/builtin/earnings/board-model.ts +13 -6
  432. package/src/plugins/builtin/earnings/board-table.ts +4 -1
  433. package/src/plugins/builtin/earnings/board.tsx +253 -50
  434. package/src/plugins/builtin/earnings/calendar-model.ts +188 -0
  435. package/src/plugins/builtin/earnings/calendar.tsx +338 -0
  436. package/src/plugins/builtin/earnings/client.ts +4 -3
  437. package/src/plugins/builtin/earnings/headless.ts +53 -15
  438. package/src/plugins/builtin/earnings/history-model.ts +53 -36
  439. package/src/plugins/builtin/earnings/index.tsx +15 -22
  440. package/src/plugins/builtin/earnings/model.ts +17 -12
  441. package/src/plugins/builtin/earnings/scope.ts +89 -0
  442. package/src/plugins/builtin/earnings-calls/calendar.tsx +310 -0
  443. package/src/plugins/builtin/earnings-calls/data.ts +146 -2
  444. package/src/plugins/builtin/earnings-calls/headless.ts +151 -9
  445. package/src/plugins/builtin/earnings-calls/index.tsx +3 -3
  446. package/src/plugins/builtin/earnings-calls/lock-note.ts +1 -1
  447. package/src/plugins/builtin/earnings-calls/pane.tsx +149 -31
  448. package/src/plugins/builtin/earnings-calls/upcoming.ts +195 -0
  449. package/src/plugins/builtin/earnings-ripple/pane.tsx +10 -5
  450. package/src/plugins/builtin/econ/calendar-model.ts +132 -20
  451. package/src/plugins/builtin/econ/detail-view.tsx +48 -10
  452. package/src/plugins/builtin/econ/fred-catalog.ts +23 -6
  453. package/src/plugins/builtin/econ/fred-series-map.ts +4 -0
  454. package/src/plugins/builtin/econ/index.tsx +112 -25
  455. package/src/plugins/builtin/econ/print-watch.ts +2 -1
  456. package/src/plugins/builtin/econ/types.ts +32 -1
  457. package/src/plugins/builtin/econ-statistics/client.ts +16 -3
  458. package/src/plugins/builtin/econ-statistics/defs.ts +4 -0
  459. package/src/plugins/builtin/econ-statistics/detail.tsx +2 -2
  460. package/src/plugins/builtin/econ-statistics/headless.ts +13 -2
  461. package/src/plugins/builtin/econ-statistics/index.tsx +3 -3
  462. package/src/plugins/builtin/econ-statistics/pane.tsx +2 -1
  463. package/src/plugins/builtin/econ-statistics/stats.ts +103 -0
  464. package/src/plugins/builtin/econ-statistics/view.ts +16 -1
  465. package/src/plugins/builtin/equity-screener/client.ts +21 -3
  466. package/src/plugins/builtin/equity-screener/headless.ts +68 -6
  467. package/src/plugins/builtin/equity-screener/live.ts +1 -1
  468. package/src/plugins/builtin/equity-screener/model.ts +6 -0
  469. package/src/plugins/builtin/equity-screener/pane.tsx +45 -10
  470. package/src/plugins/builtin/equity-screener/screen-check.ts +90 -0
  471. package/src/plugins/builtin/equity-screener/ticker-check.tsx +148 -0
  472. package/src/plugins/builtin/estimate-revisions/headless.ts +3 -1
  473. package/src/plugins/builtin/estimate-revisions/lock-note.ts +3 -3
  474. package/src/plugins/builtin/estimate-revisions/model.ts +8 -10
  475. package/src/plugins/builtin/exposure/headless.ts +51 -6
  476. package/src/plugins/builtin/exposure/index.tsx +28 -2
  477. package/src/plugins/builtin/exposure/model.ts +7 -0
  478. package/src/plugins/builtin/exposure/pane.tsx +6 -1
  479. package/src/plugins/builtin/fear-greed/index.tsx +1 -1
  480. package/src/plugins/builtin/filing-events/index.tsx +1 -1
  481. package/src/plugins/builtin/futures/model.ts +10 -9
  482. package/src/plugins/builtin/futures/returns.ts +8 -36
  483. package/src/plugins/builtin/futures/table.tsx +1 -1
  484. package/src/plugins/builtin/futures-curve/client.ts +40 -9
  485. package/src/plugins/builtin/futures-curve/headless.ts +39 -17
  486. package/src/plugins/builtin/futures-curve/model.ts +258 -69
  487. package/src/plugins/builtin/futures-curve/pane.tsx +46 -17
  488. package/src/plugins/builtin/fx-matrix/client.ts +15 -8
  489. package/src/plugins/builtin/fx-matrix/headless.ts +32 -14
  490. package/src/plugins/builtin/fx-matrix/index.tsx +13 -11
  491. package/src/plugins/builtin/fx-matrix/live-legs.ts +22 -0
  492. package/src/plugins/builtin/fx-matrix/settings.ts +2 -1
  493. package/src/plugins/builtin/gpu/headless.ts +9 -4
  494. package/src/plugins/builtin/help/index.tsx +13 -3
  495. package/src/plugins/builtin/holders/beneficial-model.ts +8 -11
  496. package/src/plugins/builtin/holders/beneficial-report.ts +6 -5
  497. package/src/plugins/builtin/holders/beneficial-view.tsx +7 -3
  498. package/src/plugins/builtin/holders/client.ts +13 -1
  499. package/src/plugins/builtin/holders/format.ts +28 -17
  500. package/src/plugins/builtin/holders/headless.ts +46 -7
  501. package/src/plugins/builtin/holders/index-holders.ts +264 -0
  502. package/src/plugins/builtin/holders/pane.tsx +79 -15
  503. package/src/plugins/builtin/holders/report-rows.ts +35 -7
  504. package/src/plugins/builtin/holders/table-model.ts +2 -1
  505. package/src/plugins/builtin/holders/treemap.tsx +2 -2
  506. package/src/plugins/builtin/insider/headless.ts +1 -1
  507. package/src/plugins/builtin/insider/signals-client.ts +1 -1
  508. package/src/plugins/builtin/insider/signals.tsx +1 -1
  509. package/src/plugins/builtin/ipo-calendar/pane.tsx +7 -4
  510. package/src/plugins/builtin/iv-history/client.ts +20 -0
  511. package/src/plugins/builtin/iv-history/headless.ts +4 -4
  512. package/src/plugins/builtin/iv-history/index.tsx +1 -1
  513. package/src/plugins/builtin/iv-history/model.ts +13 -4
  514. package/src/plugins/builtin/iv-history/series.ts +3 -1
  515. package/src/plugins/builtin/jobs/lock-note.ts +1 -1
  516. package/src/plugins/builtin/jobs/model.ts +4 -15
  517. package/src/plugins/builtin/jobs/pane.tsx +7 -5
  518. package/src/plugins/builtin/jobs/share-bars.tsx +11 -5
  519. package/src/plugins/builtin/jodi/pane.tsx +10 -4
  520. package/src/plugins/builtin/layout-manager/index.tsx +1 -0
  521. package/src/plugins/builtin/macro-day/headless.ts +20 -7
  522. package/src/plugins/builtin/macro-day/index.tsx +3 -2
  523. package/src/plugins/builtin/macro-day/model.ts +29 -8
  524. package/src/plugins/builtin/macro-day/pane.tsx +46 -10
  525. package/src/plugins/builtin/macro-day/releases.ts +55 -13
  526. package/src/plugins/builtin/market-heatmap/data.ts +9 -2
  527. package/src/plugins/builtin/market-heatmap/evidence.ts +1 -1
  528. package/src/plugins/builtin/market-heatmap/headless.ts +9 -6
  529. package/src/plugins/builtin/market-heatmap/index.tsx +3 -3
  530. package/src/plugins/builtin/market-heatmap/model.ts +10 -7
  531. package/src/plugins/builtin/market-movers/client.ts +33 -19
  532. package/src/plugins/builtin/market-movers/headless.ts +8 -2
  533. package/src/plugins/builtin/market-movers/index.tsx +16 -10
  534. package/src/plugins/builtin/market-movers/screener.ts +29 -8
  535. package/src/plugins/builtin/market-movers/session-body.tsx +4 -2
  536. package/src/plugins/builtin/market-movers/session-table.ts +4 -2
  537. package/src/plugins/builtin/market-movers/table.ts +4 -1
  538. package/src/plugins/builtin/market-valuation/headless.ts +2 -0
  539. package/src/plugins/builtin/market-valuation/view.ts +5 -0
  540. package/src/plugins/builtin/members/headless.ts +6 -5
  541. package/src/plugins/builtin/members/pane.tsx +11 -4
  542. package/src/plugins/builtin/mna/client.ts +1 -0
  543. package/src/plugins/builtin/mna/detail.tsx +20 -32
  544. package/src/plugins/builtin/mna/distress/detail.tsx +16 -4
  545. package/src/plugins/builtin/mna/distress/model.ts +3 -2
  546. package/src/plugins/builtin/mna/distress/pane.tsx +7 -4
  547. package/src/plugins/builtin/mna/headless.ts +6 -13
  548. package/src/plugins/builtin/mna/model.ts +93 -15
  549. package/src/plugins/builtin/mna/pane.tsx +5 -4
  550. package/src/plugins/builtin/news/headless.ts +12 -6
  551. package/src/plugins/builtin/news/index.tsx +10 -1
  552. package/src/plugins/builtin/news/wire/index.tsx +3 -2
  553. package/src/plugins/builtin/news/wire/news/command-bar-search.ts +26 -10
  554. package/src/plugins/builtin/news/wire/news/query-presets.ts +6 -2
  555. package/src/plugins/builtin/news/wire/rss/cli.ts +3 -3
  556. package/src/plugins/builtin/notes/cli.ts +49 -14
  557. package/src/plugins/builtin/openfda/pane.tsx +1 -1
  558. package/src/plugins/builtin/options/carry.ts +2 -2
  559. package/src/plugins/builtin/options/index.tsx +1 -1
  560. package/src/plugins/builtin/options/view.tsx +10 -10
  561. package/src/plugins/builtin/options-calculator/headless.ts +46 -7
  562. package/src/plugins/builtin/options-scenario/client.ts +123 -28
  563. package/src/plugins/builtin/options-scenario/collar.ts +8 -6
  564. package/src/plugins/builtin/options-scenario/csp-screen-headless.ts +127 -0
  565. package/src/plugins/builtin/options-scenario/csp-screen-pane.tsx +165 -0
  566. package/src/plugins/builtin/options-scenario/csp-screen.ts +258 -0
  567. package/src/plugins/builtin/options-scenario/csp.ts +101 -21
  568. package/src/plugins/builtin/options-scenario/headless.ts +36 -15
  569. package/src/plugins/builtin/options-scenario/hedge.ts +20 -14
  570. package/src/plugins/builtin/options-scenario/index.tsx +28 -3
  571. package/src/plugins/builtin/options-scenario/model.ts +13 -0
  572. package/src/plugins/builtin/options-scenario/pane.tsx +9 -5
  573. package/src/plugins/builtin/perps/equity-row.tsx +11 -3
  574. package/src/plugins/builtin/perps/freshness.ts +8 -5
  575. package/src/plugins/builtin/perps/headless.ts +3 -1
  576. package/src/plugins/builtin/perps/list-perpetuals.ts +25 -4
  577. package/src/plugins/builtin/perps/live-rows.ts +161 -0
  578. package/src/plugins/builtin/perps/markets-section.tsx +154 -0
  579. package/src/plugins/builtin/perps/pane.tsx +36 -17
  580. package/src/plugins/builtin/perps/venue-markets.ts +96 -0
  581. package/src/plugins/builtin/plugin-marketplace/index.tsx +2 -1
  582. package/src/plugins/builtin/plugin-marketplace/pane.tsx +143 -59
  583. package/src/plugins/builtin/portfolio-list/cli/bulk-symbols.ts +72 -24
  584. package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +158 -141
  585. package/src/plugins/builtin/portfolio-list/cli/render.ts +49 -20
  586. package/src/plugins/builtin/portfolio-list/cli/shared.ts +3 -3
  587. package/src/plugins/builtin/portfolio-list/cli/watchlist-command.ts +29 -24
  588. package/src/plugins/builtin/portfolio-list/headless.ts +6 -3
  589. package/src/plugins/builtin/portfolio-list/income.ts +13 -2
  590. package/src/plugins/builtin/portfolio-list/index.tsx +9 -2
  591. package/src/plugins/builtin/portfolio-list/pane/index.tsx +21 -8
  592. package/src/plugins/builtin/portfolio-list/pane/purchase-date-fx.ts +46 -0
  593. package/src/plugins/builtin/portfolio-list/summary/live-accounts.ts +16 -9
  594. package/src/plugins/builtin/portfolio-list/summary/totals.ts +2 -15
  595. package/src/plugins/builtin/power/client.ts +4 -1
  596. package/src/plugins/builtin/power/evidence.ts +22 -7
  597. package/src/plugins/builtin/power/gas.tsx +5 -1
  598. package/src/plugins/builtin/power/pane.tsx +8 -1
  599. package/src/plugins/builtin/power/prices.tsx +10 -3
  600. package/src/plugins/builtin/research/analyst-headless.ts +25 -8
  601. package/src/plugins/builtin/research/analyst-model.ts +68 -3
  602. package/src/plugins/builtin/research/corporate-actions-pane.tsx +63 -14
  603. package/src/plugins/builtin/research/event-model.ts +3 -1
  604. package/src/plugins/builtin/research/event-sources.ts +12 -4
  605. package/src/plugins/builtin/research/index.tsx +2 -1
  606. package/src/plugins/builtin/research/relative-valuation-basis.ts +58 -0
  607. package/src/plugins/builtin/research/relative-valuation-columns.ts +31 -2
  608. package/src/plugins/builtin/research/relative-valuation-currency.ts +12 -5
  609. package/src/plugins/builtin/research/relative-valuation-headless.ts +84 -26
  610. package/src/plugins/builtin/research/relative-valuation-model.ts +88 -19
  611. package/src/plugins/builtin/research/relative-valuation-pane.tsx +76 -9
  612. package/src/plugins/builtin/research/relative-valuation-peers.ts +1 -1
  613. package/src/plugins/builtin/reverse-dcf/model.ts +6 -2
  614. package/src/plugins/builtin/risk-factors/index.tsx +2 -2
  615. package/src/plugins/builtin/scanner/lock-note.ts +1 -1
  616. package/src/plugins/builtin/sec/forms.ts +13 -0
  617. package/src/plugins/builtin/sec/fund-abroad.ts +32 -0
  618. package/src/plugins/builtin/sec/fund-facts.ts +68 -8
  619. package/src/plugins/builtin/sec/headless.ts +85 -8
  620. package/src/plugins/builtin/sec/index.tsx +58 -12
  621. package/src/plugins/builtin/sectors/client.ts +2 -1
  622. package/src/plugins/builtin/sectors/sector-model.ts +11 -15
  623. package/src/plugins/builtin/series-inventory.ts +2 -0
  624. package/src/plugins/builtin/shared/broker-reconnect.ts +107 -22
  625. package/src/plugins/builtin/shared/cloud-upgrade.ts +34 -6
  626. package/src/plugins/builtin/shared/earnings-calendar.ts +375 -0
  627. package/src/plugins/builtin/{earnings/estimate-basis.ts → shared/earnings-estimate-basis.ts} +1 -1
  628. package/src/plugins/builtin/shared/earnings-report.ts +3 -3
  629. package/src/plugins/builtin/shared/fx-rate-freshness.ts +23 -1
  630. package/src/plugins/builtin/shared/job-posting.ts +129 -0
  631. package/src/plugins/builtin/shared/pro-lock-note.ts +3 -3
  632. package/src/plugins/builtin/shared/report-freshness.ts +3 -0
  633. package/src/plugins/builtin/shared/research-trading.tsx +21 -0
  634. package/src/plugins/builtin/shared/series-cache.ts +2 -0
  635. package/src/plugins/builtin/shared/ticker-surface.ts +2 -1
  636. package/src/plugins/builtin/short-interest/client.ts +2 -0
  637. package/src/plugins/builtin/short-interest/headless.ts +41 -12
  638. package/src/plugins/builtin/short-interest/index.tsx +23 -1
  639. package/src/plugins/builtin/short-interest/model.ts +70 -19
  640. package/src/plugins/builtin/short-interest/pane.tsx +19 -2
  641. package/src/plugins/builtin/short-interest/publications-client.ts +82 -0
  642. package/src/plugins/builtin/short-interest/publications-headless.ts +29 -0
  643. package/src/plugins/builtin/short-interest/publications-model.ts +50 -0
  644. package/src/plugins/builtin/short-interest/publications-pane.tsx +66 -0
  645. package/src/plugins/builtin/short-interest/schedule.ts +35 -2
  646. package/src/plugins/builtin/short-interest/surface.tsx +11 -4
  647. package/src/plugins/builtin/short-interest/types.ts +9 -0
  648. package/src/plugins/builtin/short-interest/watch-client.ts +14 -8
  649. package/src/plugins/builtin/short-interest/watch-model.ts +12 -25
  650. package/src/plugins/builtin/short-interest/watch-pane.tsx +5 -1
  651. package/src/plugins/builtin/supply-chain/flow.tsx +33 -9
  652. package/src/plugins/builtin/supply-chain/model.ts +51 -3
  653. package/src/plugins/builtin/supply-chain/pane.tsx +78 -39
  654. package/src/plugins/builtin/supply-chain/row-evidence.tsx +1 -1
  655. package/src/plugins/builtin/themes/headless.ts +8 -5
  656. package/src/plugins/builtin/themes/model.ts +14 -4
  657. package/src/plugins/builtin/themes/pane.tsx +24 -5
  658. package/src/plugins/builtin/thirteenf/headless.ts +5 -5
  659. package/src/plugins/builtin/thirteenf/signals.ts +3 -1
  660. package/src/plugins/builtin/ticker-detail/adr-pair/headless.ts +123 -0
  661. package/src/plugins/builtin/ticker-detail/adr-pair/model.ts +132 -0
  662. package/src/plugins/builtin/ticker-detail/adr-pair/tab.tsx +87 -0
  663. package/src/plugins/builtin/ticker-detail/data-panes/historical-prices.tsx +40 -26
  664. package/src/plugins/builtin/ticker-detail/data-panes/history-bars.ts +8 -4
  665. package/src/plugins/builtin/ticker-detail/data-panes/returns-history.ts +67 -3
  666. package/src/plugins/builtin/ticker-detail/data-panes/returns-model.ts +112 -5
  667. package/src/plugins/builtin/ticker-detail/data-panes/returns-pane.tsx +17 -2
  668. package/src/plugins/builtin/ticker-detail/financials/aggregation.ts +21 -7
  669. package/src/plugins/builtin/ticker-detail/financials/model.ts +36 -1
  670. package/src/plugins/builtin/ticker-detail/financials/offerings.ts +56 -0
  671. package/src/plugins/builtin/ticker-detail/financials/ratios.ts +62 -13
  672. package/src/plugins/builtin/ticker-detail/financials/tab.tsx +30 -4
  673. package/src/plugins/builtin/ticker-detail/headless-schema.ts +14 -2
  674. package/src/plugins/builtin/ticker-detail/headless.ts +148 -35
  675. package/src/plugins/builtin/ticker-detail/index.tsx +37 -5
  676. package/src/plugins/builtin/ticker-detail/overview/model.ts +65 -10
  677. package/src/plugins/builtin/ticker-detail/overview/pane.tsx +9 -1
  678. package/src/plugins/builtin/ticker-detail/overview-tab.tsx +68 -11
  679. package/src/plugins/builtin/ticker-detail/pane.tsx +11 -0
  680. package/src/plugins/builtin/ticker-detail/quote-footer.ts +8 -3
  681. package/src/plugins/builtin/ticker-detail/research-tabs.ts +11 -0
  682. package/src/plugins/builtin/vol-surface/client.ts +5 -4
  683. package/src/plugins/builtin/vol-surface/headless.ts +12 -3
  684. package/src/plugins/builtin/vol-surface/model.ts +4 -2
  685. package/src/plugins/builtin/volatility/model.ts +5 -10
  686. package/src/plugins/builtin/world-venue-map/basemap-layer.tsx +4 -3
  687. package/src/plugins/builtin/world-venue-map/basemap.ts +3 -1
  688. package/src/plugins/builtin/world-venue-map/chokepoint-chart.ts +40 -0
  689. package/src/plugins/builtin/world-venue-map/evidence.ts +1 -1
  690. package/src/plugins/builtin/world-venue-map/geo-series.ts +90 -11
  691. package/src/plugins/builtin/world-venue-map/headless.ts +1 -1
  692. package/src/plugins/builtin/world-venue-map/index.ts +3 -26
  693. package/src/plugins/builtin/world-venue-map/layers.ts +1 -1
  694. package/src/plugins/builtin/world-venue-map/map.tsx +2 -1
  695. package/src/plugins/builtin/world-venue-map/pane.tsx +4 -2
  696. package/src/plugins/builtin/world-venue-map/venue-header.tsx +15 -4
  697. package/src/plugins/builtin/yield-curve/client.ts +25 -0
  698. package/src/plugins/builtin/yield-curve/curves.ts +7 -4
  699. package/src/plugins/builtin/yield-curve/headless.ts +38 -4
  700. package/src/plugins/builtin/yield-curve/history.ts +4 -3
  701. package/src/plugins/builtin/yield-curve/index.tsx +12 -6
  702. package/src/plugins/builtin/yield-curve/swaps-model.ts +93 -0
  703. package/src/plugins/builtin/yield-curve/swaps.tsx +99 -0
  704. package/src/plugins/bundle.ts +1 -1
  705. package/src/plugins/catalog-browser.ts +2 -1
  706. package/src/plugins/compat.ts +3 -3
  707. package/src/plugins/dependencies.ts +75 -14
  708. package/src/plugins/extracted-plugins.ts +132 -34
  709. package/src/plugins/host-link.ts +149 -34
  710. package/src/plugins/installer.ts +35 -10
  711. package/src/plugins/loader.ts +206 -38
  712. package/src/plugins/manager-node.ts +2 -2
  713. package/src/plugins/marketplace/deactivation.ts +22 -0
  714. package/src/plugins/marketplace/model.ts +2 -2
  715. package/src/plugins/marketplace/packs.ts +1 -1
  716. package/src/plugins/ownership.ts +1 -1
  717. package/src/plugins/peer-retry.ts +155 -0
  718. package/src/plugins/registry/contributions.ts +3 -1
  719. package/src/plugins/registry/index.ts +4 -3
  720. package/src/plugins/registry/plugin-state.ts +3 -0
  721. package/src/plugins/seed-notice.ts +20 -0
  722. package/src/plugins/shortcut-argument.ts +39 -0
  723. package/src/portfolio/allocation.ts +1 -1
  724. package/src/portfolio/collection-name.ts +31 -0
  725. package/src/portfolio/column-values.ts +10 -8
  726. package/src/portfolio/cost-fx.ts +296 -19
  727. package/src/portfolio/manual-lots.ts +75 -0
  728. package/src/portfolio/mutations.ts +60 -22
  729. package/src/portfolio/suffixed-listings.ts +209 -0
  730. package/src/portfolio/totals-currency.ts +24 -0
  731. package/src/public/__snapshots__/public-api.test.ts.snap +14 -0
  732. package/src/public/time-series.ts +11 -8
  733. package/src/remote/schema.ts +1 -1
  734. package/src/renderers/browser/config-host.ts +3 -0
  735. package/src/renderers/browser/main.tsx +23 -3
  736. package/src/renderers/dom/boot-frame-page.ts +187 -0
  737. package/src/renderers/dom/boot-frame.ts +237 -0
  738. package/src/renderers/dom/build-assets.ts +46 -8
  739. package/src/renderers/dom/dom-ui-host.tsx +4 -29
  740. package/src/renderers/dom/host/ascii-text.ts +16 -2
  741. package/src/renderers/dom/host/box.tsx +43 -2
  742. package/src/renderers/dom/host/chart-surface.tsx +2 -0
  743. package/src/renderers/dom/host/hls.chunk.ts +3 -0
  744. package/src/renderers/dom/host/image-surface.tsx +49 -0
  745. package/src/renderers/dom/host/media-surface.tsx +24 -18
  746. package/src/renderers/dom/host/mouse.ts +30 -0
  747. package/src/renderers/dom/host/size-observer.ts +1 -1
  748. package/src/renderers/dom/host/style.ts +1 -1
  749. package/src/renderers/dom/styles.css +76 -0
  750. package/src/renderers/dom/test-utils.tsx +2 -1
  751. package/src/renderers/electrobun/bun/application-menu/index.ts +3 -3
  752. package/src/renderers/electrobun/bun/desktop/backend-requests.ts +3 -0
  753. package/src/renderers/electrobun/bun/desktop/backend.ts +46 -3
  754. package/src/renderers/electrobun/bun/desktop/detached-windows.ts +1 -1
  755. package/src/renderers/electrobun/bun/desktop/host-requests.ts +9 -3
  756. package/src/renderers/electrobun/bun/desktop/initialization.ts +81 -18
  757. package/src/renderers/electrobun/bun/external-plugins.ts +29 -7
  758. package/src/renderers/electrobun/bun/index.ts +11 -1
  759. package/src/renderers/electrobun/bun/window/boot-frame.ts +67 -0
  760. package/src/renderers/electrobun/bun/window/create.ts +4 -1
  761. package/src/renderers/electrobun/shared/boot-frame.ts +7 -0
  762. package/src/renderers/electrobun/shared/protocol.ts +6 -1
  763. package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +1 -1
  764. package/src/renderers/electrobun/view/config-host.ts +3 -0
  765. package/src/renderers/electrobun/view/fatal-screen.tsx +1 -1
  766. package/src/renderers/electrobun/view/main.tsx +30 -4
  767. package/src/renderers/electrobun/view/news-source.ts +5 -5
  768. package/src/renderers/electrobun/view/remote/asset-data-client.ts +1 -1
  769. package/src/renderers/electrobun/view/ui-host.tsx +1 -1
  770. package/src/renderers/opentui/browser-open.ts +88 -0
  771. package/src/renderers/opentui/host.tsx +5 -14
  772. package/src/renderers/opentui/image/loader.ts +3 -2
  773. package/src/renderers/opentui/native-smoke.ts +10 -1
  774. package/src/renderers/opentui/pane-image/index.ts +2 -1
  775. package/src/renderers/opentui/render-lib.ts +253 -0
  776. package/src/renderers/opentui/render-timing-smoke.ts +1 -1
  777. package/src/renderers/opentui/start.tsx +1 -1
  778. package/src/renderers/share/layout-view.tsx +2 -2
  779. package/src/renderers/share/main.tsx +4 -4
  780. package/src/renderers/share/view.tsx +1 -1
  781. package/src/series/resolve.ts +22 -6
  782. package/src/series/standalone.ts +30 -2
  783. package/src/series/types.ts +8 -1
  784. package/src/shares/api.ts +4 -1
  785. package/src/shares/pane.ts +1 -1
  786. package/src/sources/gloomberb-cloud/fred-series.ts +46 -1
  787. package/src/sources/gloomberb-cloud/index.ts +32 -16
  788. package/src/sources/gloomberb-cloud/news.ts +39 -0
  789. package/src/sources/gloomberb-cloud/normalizers.ts +14 -1
  790. package/src/sources/gloomberb-cloud/perpetuals.ts +49 -1
  791. package/src/sources/listing-symbols.ts +37 -0
  792. package/src/sources/provider-errors.ts +16 -2
  793. package/src/sources/provider-router/financial-routes.ts +21 -3
  794. package/src/sources/provider-router/financials.ts +15 -2
  795. package/src/sources/provider-router/history.ts +30 -8
  796. package/src/sources/provider-router/primary.ts +1 -1
  797. package/src/state/app/bootstrap.ts +23 -0
  798. package/src/state/hooks/inline-tickers.ts +30 -5
  799. package/src/sync/controller.ts +1 -1
  800. package/src/sync/core-contributors.ts +46 -14
  801. package/src/team/collections-sync.ts +2 -1
  802. package/src/team/collections.ts +178 -17
  803. package/src/telemetry/crash-reports.ts +17 -4
  804. package/src/test-support/builtin-panes.ts +1 -1
  805. package/src/theme/colors.ts +3 -30
  806. package/src/theme/ui-tokens.ts +37 -1
  807. package/src/tickers/company-name-listing.ts +210 -33
  808. package/src/tickers/index-roots.ts +47 -0
  809. package/src/tickers/instrument-label.ts +5 -1
  810. package/src/tickers/metadata.ts +10 -0
  811. package/src/tickers/perpetual-listing.ts +5 -2
  812. package/src/tickers/search/home-listing.ts +75 -0
  813. package/src/tickers/search/index.ts +76 -27
  814. package/src/tickers/search/ranking.ts +54 -4
  815. package/src/tickers/search/upsert.ts +29 -0
  816. package/src/tickers/terminal-codes.ts +416 -40
  817. package/src/time-series/bar-aggregation.ts +243 -0
  818. package/src/time-series/base-series.ts +307 -0
  819. package/src/time-series/chart-bounds.ts +349 -0
  820. package/src/time-series/chart-seed.ts +142 -0
  821. package/src/time-series/economic.ts +5 -0
  822. package/src/time-series/fundamentals.ts +18 -3
  823. package/src/time-series/history-acquisition.ts +499 -0
  824. package/src/time-series/leverage.ts +100 -0
  825. package/src/time-series/market-resolution.ts +4 -2
  826. package/src/time-series/market.ts +2 -1
  827. package/src/time-series/price-comparison.ts +175 -30
  828. package/src/time-series/range.ts +9 -1
  829. package/src/time-series/resolution.ts +174 -16
  830. package/src/time-series/resolve-context.ts +157 -0
  831. package/src/time-series/resolve.ts +126 -1577
  832. package/src/time-series/series-name.ts +38 -0
  833. package/src/time-series/series-presentation.ts +208 -0
  834. package/src/time-series/spec.ts +11 -6
  835. package/src/time-series/studies.ts +109 -12
  836. package/src/time-series/tail-reconcile.ts +121 -0
  837. package/src/time-series/types.ts +29 -2
  838. package/src/time-series/use-chart-resolution.ts +4 -5
  839. package/src/types/broker.ts +10 -0
  840. package/src/types/config.ts +14 -0
  841. package/src/types/data-provider.ts +14 -0
  842. package/src/types/exchange-rate.ts +6 -0
  843. package/src/types/financials.ts +104 -7
  844. package/src/types/headless.ts +76 -6
  845. package/src/types/instrument.ts +3 -0
  846. package/src/types/plugin.ts +65 -8
  847. package/src/types/price-history.ts +2 -0
  848. package/src/types/ticker.ts +13 -0
  849. package/src/types/trading.ts +59 -1
  850. package/src/ui/ascii-font.ts +13 -1
  851. package/src/ui/host.tsx +6 -1
  852. package/src/updater/command-names.ts +175 -0
  853. package/src/updater/index.ts +10 -5
  854. package/src/utils/calendar-date.ts +32 -15
  855. package/src/utils/cash-runway.ts +241 -0
  856. package/src/utils/central-banks.ts +42 -0
  857. package/src/utils/cli-output.ts +259 -80
  858. package/src/utils/contract-month.ts +16 -0
  859. package/src/utils/crypto-pair.ts +61 -3
  860. package/src/utils/currency-units.ts +29 -0
  861. package/src/utils/datetime-format.ts +10 -0
  862. package/src/utils/debug-log.ts +1 -1
  863. package/src/utils/decimal-comma.ts +39 -6
  864. package/src/utils/exchange-announcements.ts +71 -0
  865. package/src/utils/exchange-rate-snapshot.ts +10 -0
  866. package/src/utils/financial-statements.ts +83 -4
  867. package/src/utils/format.ts +34 -16
  868. package/src/utils/fundamentals.ts +150 -34
  869. package/src/utils/fx-market-hours.ts +10 -1
  870. package/src/utils/latest-financial-period.ts +8 -0
  871. package/src/utils/linux-libc.ts +54 -0
  872. package/src/utils/market-capitalization.ts +111 -15
  873. package/src/utils/max-drawdown.ts +64 -0
  874. package/src/utils/network-failure.ts +83 -0
  875. package/src/utils/option-expiry.ts +139 -7
  876. package/src/utils/price-earnings.ts +11 -5
  877. package/src/utils/price-history.ts +18 -8
  878. package/src/utils/price-window.ts +131 -0
  879. package/src/utils/release-date.ts +47 -0
  880. package/src/utils/sec.ts +3 -0
  881. package/src/utils/throttled-fetch.ts +11 -4
  882. package/src/utils/trailing-eps.ts +67 -0
  883. package/src/utils/typed-text.ts +21 -0
  884. package/src/utils/utc-time.ts +24 -1
  885. package/src/version.ts +6 -0
  886. package/src/cli/pane-functions/screenshot.ts +0 -2122
@@ -10,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
 
@@ -31,6 +31,8 @@ export function signedInBrokerForProfile(instance: BrokerInstanceConfig, fallbac
31
31
  export interface ConnectSignedInBrokerDeps<T> {
32
32
  getConfig(): AppConfig;
33
33
  createBrokerInstance(brokerType: string, label: string, values: Record<string, unknown>): Promise<BrokerInstanceConfig>;
34
+ /** Turns a profile that was turned off back on. */
35
+ enableBrokerInstance(instanceId: string): Promise<void>;
34
36
  syncBrokerInstance(instanceId: string): Promise<T>;
35
37
  /** Asks the user to connect: a form's own connect step, or the connect dialog when missing. */
36
38
  requestSignIn?: (broker: SignedInBroker) => Promise<boolean>;
@@ -39,6 +41,9 @@ export interface ConnectSignedInBrokerDeps<T> {
39
41
  /**
40
42
  * Asks the user to connect `broker`, then syncs its profile, creating it the
41
43
  * first time. Resolves null when the broker was not connected.
44
+ *
45
+ * Connecting a broker whose profile is turned off turns it back on first:
46
+ * nothing syncs a disabled profile, and connecting it again is asking for it.
42
47
  */
43
48
  export async function connectSignedInBrokerProfile<T>(
44
49
  broker: SignedInBroker,
@@ -46,8 +51,11 @@ export async function connectSignedInBrokerProfile<T>(
46
51
  ): Promise<{ instance: BrokerInstanceConfig; synced: T } | null> {
47
52
  const connected = await (deps.requestSignIn ?? requestBrokerSignIn)(broker);
48
53
  if (!connected) return null;
49
- const instance = findSignedInBrokerProfile(deps.getConfig().brokerInstances, broker.id)
50
- ?? await deps.createBrokerInstance(SIGNED_IN_BROKER_TYPE, broker.name, { connectionMode: broker.id, broker: broker.id });
54
+ const existing = findSignedInBrokerProfile(deps.getConfig().brokerInstances, broker.id);
55
+ if (existing?.enabled === false) await deps.enableBrokerInstance(existing.id);
56
+ const instance = existing
57
+ ? { ...existing, enabled: true }
58
+ : await deps.createBrokerInstance(SIGNED_IN_BROKER_TYPE, broker.name, { connectionMode: broker.id, broker: broker.id });
51
59
  return { instance, synced: await deps.syncBrokerInstance(instance.id) };
52
60
  }
53
61
 
@@ -7,6 +7,7 @@ import type { BrokerAccount } from "../types/trading";
7
7
  import type { TickerRecord } from "../types/ticker";
8
8
  import { getBrokerInstance } from "../utils/broker-instances";
9
9
  import {
10
+ accountsHeldUnderOwnNumber,
10
11
  clearBrokerInstanceTickerData,
11
12
  clearLeftoverBrokerHoldings,
12
13
  ensureBrokerPortfolio,
@@ -248,6 +249,13 @@ export async function syncBrokerInstance({
248
249
  throwIfBrokerImportCancelled(signal);
249
250
  }
250
251
 
252
+ // An account another profile holds under its own number stays with it.
253
+ const heldUnderOwnNumber = accountsHeldUnderOwnNumber(config, instance, brokerAccounts);
254
+ if (heldUnderOwnNumber.size > 0) {
255
+ brokerAccounts = brokerAccounts.filter((account) => !heldUnderOwnNumber.has(account.accountId));
256
+ positions = positions.filter((position) => !position.accountId || !heldUnderOwnNumber.has(position.accountId));
257
+ }
258
+
251
259
  const accountMetadata = new Map(
252
260
  brokerAccounts.map((account) => [
253
261
  account.accountId,
@@ -301,7 +309,7 @@ export async function syncBrokerInstance({
301
309
  const account = accountMetadata.get(accountId);
302
310
  claimPortfolio(portfolioId, account?.name || accountId, account?.currency || "USD", accountId);
303
311
  }
304
- } else {
312
+ } else if (heldUnderOwnNumber.size === 0) {
305
313
  const defaultAccount = brokerAccounts[0];
306
314
  const portfolioId = findReusableBrokerPortfolioId(nextConfig, instance, defaultAccount?.accountId, portfolioBrokerId);
307
315
  const fallbackName = defaultAccount?.name || defaultAccount?.accountId || instance.label || broker.name;
@@ -9,7 +9,8 @@ import type {
9
9
  SeriesTransform,
10
10
  TimeSeriesPoint,
11
11
  } from "../time-series/types";
12
- import { CHART_RESOLUTIONS, TIME_RANGES } from "../time-series/range";
12
+ import { TIME_RANGES } from "../time-series/range";
13
+ import { isChartResolution } from "../time-series/resolution";
13
14
  import type {
14
15
  CapabilityInvoker,
15
16
  CapabilitySchema,
@@ -26,7 +27,6 @@ const CAPABILITY_ID_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._-]{0,79}$/;
26
27
  const SERIES_ID_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._~%:/-]{0,239}$/;
27
28
  const chartSeriesLog = debugLog.createLogger("chart-series");
28
29
  const ranges = new Set<string>(TIME_RANGES);
29
- const resolutions = new Set<string>(CHART_RESOLUTIONS);
30
30
  const periods = new Set(["auto", "daily", "weekly", "monthly", "quarterly", "annual", "ttm"]);
31
31
  const styles = new Set(["line", "area", "step", "columns", "points", "candles", "ohlc", "hlc"]);
32
32
  const transforms = new Set(["raw", "percent", "index100", "yoy", "qoq", "log"]);
@@ -103,7 +103,8 @@ function viewport(value: unknown): ChartViewportSpec {
103
103
  const input = object(value, "resolve viewport");
104
104
  onlyKeys(input, "resolve viewport", ["range", "resolution", "dateWindow", "maxPoints"]);
105
105
  const range = enumValue<ChartViewportSpec["range"]>(input.range, "viewport range", ranges);
106
- const resolution = enumValue<ChartViewportSpec["resolution"]>(input.resolution, "viewport resolution", resolutions);
106
+ if (!isChartResolution(input.resolution)) fail("viewport resolution", `unsupported value ${String(input.resolution)}.`);
107
+ const resolution = input.resolution;
107
108
  let dateWindow: ChartViewportSpec["dateWindow"];
108
109
  if (input.dateWindow !== undefined) {
109
110
  const window = object(input.dateWindow, "viewport date window");
@@ -276,12 +277,15 @@ function searchableChartSeriesManifests(invoker: CapabilityInvoker) {
276
277
  return chartSeriesCapabilityManifests(invoker).filter((manifest) => manifest.sourceId !== REGISTERED_SERIES_SOURCE_ID);
277
278
  }
278
279
 
279
- export async function searchChartSeriesCapabilities(
280
+ type CatalogSuggestion = ChartSeriesCatalogItem & { capabilityId: string; capabilityName: string };
281
+
282
+ /** Partial search results retain failures for the shared picker error state. */
283
+ export async function searchChartSeriesCatalogs(
280
284
  invoker: CapabilityInvoker,
281
285
  query: string,
282
286
  limit = 8,
283
287
  signal?: AbortSignal,
284
- ): Promise<Array<ChartSeriesCatalogItem & { capabilityId: string; capabilityName: string }>> {
288
+ ): Promise<{ items: CatalogSuggestion[]; errors: string[] }> {
285
289
  const manifests = searchableChartSeriesManifests(invoker);
286
290
  const results = await Promise.allSettled(manifests.map(async (manifest) => {
287
291
  const items = await invoker.invokeCapability<ChartSeriesCatalogItem[]>(
@@ -297,15 +301,27 @@ export async function searchChartSeriesCapabilities(
297
301
  }));
298
302
  }));
299
303
  if (signal?.aborted) throw signal.reason ?? new DOMException("Aborted", "AbortError");
304
+ const errors: string[] = [];
300
305
  for (const [index, result] of results.entries()) {
301
306
  if (result.status === "rejected") {
307
+ errors.push(`${manifests[index]!.name} search unavailable.`);
302
308
  chartSeriesLog.warn("Chart series provider catalog failed", {
303
309
  capabilityId: manifests[index]?.id,
304
310
  error: result.reason instanceof Error ? result.reason.message : String(result.reason),
305
311
  });
306
312
  }
307
313
  }
308
- return results.flatMap((result) => result.status === "fulfilled" ? result.value : []).slice(0, limit);
314
+ return { items: results.flatMap((result) => result.status === "fulfilled" ? result.value : []).slice(0, limit), errors };
315
+ }
316
+
317
+ /** The public list-only API keeps its existing partial-results contract. */
318
+ export async function searchChartSeriesCapabilities(
319
+ invoker: CapabilityInvoker,
320
+ query: string,
321
+ limit = 8,
322
+ signal?: AbortSignal,
323
+ ): Promise<CatalogSuggestion[]> {
324
+ return (await searchChartSeriesCatalogs(invoker, query, limit, signal)).items;
309
325
  }
310
326
 
311
327
  export function chartSeriesSourceKey(
@@ -31,7 +31,7 @@ export function nimCommand(symbol: string): string {
31
31
  const definition = JSON.stringify({
32
32
  version: 1, currency: null, criteria: [{ field: "symbol", op: "in", value: [symbol] }], sort: { field: "symbol", direction: "asc" },
33
33
  });
34
- return `gloomberb fn EQS --metric kpiNimPercent --definition '${definition}'`;
34
+ return `gloom fn EQS --metric kpiNimPercent --definition '${definition}'`;
35
35
  }
36
36
 
37
37
  /** Gloom Cloud's note for a company with no US GAAP deposits tag, which reads as if it filed 10-Qs; a foreign issuer files neither. */