gloomberb 0.17.5 → 0.18.0

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 (922) hide show
  1. package/README.md +2 -0
  2. package/README.zh-CN.md +2 -0
  3. package/package.json +8 -1
  4. package/patches/electrobun@1.18.1.patch +74 -0
  5. package/src/account/auth-model.ts +3 -2
  6. package/src/account/device-signin-dialog.tsx +38 -13
  7. package/src/account/device-signin.ts +2 -1
  8. package/src/account/upgrade-dialog.tsx +6 -2
  9. package/src/api-client/askg.ts +5 -3
  10. package/src/api-client/bank-figures.ts +73 -0
  11. package/src/api-client/chat.ts +9 -0
  12. package/src/api-client/commodity-balances.ts +77 -0
  13. package/src/api-client/credit-boards.ts +21 -1
  14. package/src/api-client/crypto-markets.ts +88 -1
  15. package/src/api-client/data.ts +135 -6
  16. package/src/api-client/debt-maturities.ts +18 -0
  17. package/src/api-client/earnings.ts +10 -0
  18. package/src/api-client/equity-screener.ts +3 -0
  19. package/src/api-client/errors.ts +13 -0
  20. package/src/api-client/fund-facts.ts +72 -0
  21. package/src/api-client/futures-curve.ts +26 -3
  22. package/src/api-client/geo.ts +11 -1
  23. package/src/api-client/index.ts +30 -2
  24. package/src/api-client/insider-signals.ts +159 -0
  25. package/src/api-client/market-discovery.ts +1 -1
  26. package/src/api-client/normalizers.ts +2 -0
  27. package/src/api-client/paths.ts +28 -0
  28. package/src/api-client/request.ts +11 -3
  29. package/src/api-client/research-activity.ts +15 -8
  30. package/src/api-client/socket.ts +16 -3
  31. package/src/api-client/supply-chain-graph.ts +2 -2
  32. package/src/api-client/supply-chain.ts +8 -0
  33. package/src/api-client/tape.ts +12 -0
  34. package/src/api-client/types.ts +91 -3
  35. package/src/api-client/upgrade-experiment.ts +4 -3
  36. package/src/api-client/wall-experiments.ts +5 -3
  37. package/src/api-client/wall-summary.ts +3 -1
  38. package/src/api-client/web-experiments.ts +5 -2
  39. package/src/api-client/yield-curves.ts +17 -0
  40. package/src/app/command-bar-intro.ts +38 -0
  41. package/src/app/keybindings/actions.ts +1 -1
  42. package/src/app/pane-runtime/pane-template-runtime.ts +35 -7
  43. package/src/app/pane-runtime/plugin-bindings.ts +4 -0
  44. package/src/app/pane-runtime/ticker-open-runtime.ts +4 -14
  45. package/src/app/pane-runtime/ticker-open-target.ts +31 -0
  46. package/src/app/runtime/broker-import.ts +23 -21
  47. package/src/app/runtime/desktop-deeplink.ts +3 -4
  48. package/src/app/runtime/plugin-bindings.ts +16 -9
  49. package/src/app/runtime/startup.ts +3 -4
  50. package/src/app/runtime/ticker-refresh.ts +13 -12
  51. package/src/app/runtime/update.ts +17 -3
  52. package/src/architecture/core-builtin-allowlist.json +2 -13
  53. package/src/architecture/silent-catch-allowlist.json +3 -0
  54. package/src/architecture/ui-literals-allowlist.json +186 -0
  55. package/src/architecture/ui-tokens-allowlist.json +40 -0
  56. package/src/ask-gloom/pane-context.ts +3 -1
  57. package/src/brokers/broker-portfolio-sync.ts +66 -0
  58. package/src/brokers/signed-in/catalog.ts +2 -1
  59. package/src/brokers/signed-in/client.ts +7 -2
  60. package/src/brokers/signed-in/sign-in-dialog.tsx +120 -26
  61. package/src/brokers/signed-in/sign-in.ts +22 -20
  62. package/src/brokers/sync-broker-instance.ts +77 -42
  63. package/src/capabilities/chart-series.ts +2 -0
  64. package/src/capabilities/registry.ts +1 -3
  65. package/src/cli/bank-section.ts +147 -0
  66. package/src/cli/base-converter.ts +5 -2
  67. package/src/cli/board-coins.ts +70 -0
  68. package/src/cli/commands/fred-series.ts +90 -0
  69. package/src/cli/commands/market.ts +434 -96
  70. package/src/cli/commands/news-search.ts +35 -2
  71. package/src/cli/commands/options-chain.ts +25 -9
  72. package/src/cli/commands/options-leaps.ts +3 -3
  73. package/src/cli/commands/overview.ts +130 -40
  74. package/src/cli/commands/plugins.ts +1 -0
  75. package/src/cli/commands/search.ts +87 -24
  76. package/src/cli/commands/system.ts +5 -2
  77. package/src/cli/commands/ticker.ts +361 -64
  78. package/src/cli/context.ts +15 -1
  79. package/src/cli/desktop-pane-shot.ts +11 -3
  80. package/src/cli/earnings-calendar.ts +2 -1
  81. package/src/cli/errors.ts +25 -2
  82. package/src/cli/export-source.ts +18 -3
  83. package/src/cli/fx-pair.ts +77 -0
  84. package/src/cli/glossary.ts +196 -14
  85. package/src/cli/history-rows.ts +84 -19
  86. package/src/cli/index-roots.ts +26 -0
  87. package/src/cli/index.ts +57 -20
  88. package/src/cli/known-gaps.ts +156 -22
  89. package/src/cli/listing-arg.ts +217 -150
  90. package/src/cli/listing-suggestion.ts +7 -23
  91. package/src/cli/name-entries.ts +76 -0
  92. package/src/cli/not-a-ticker.ts +15 -6
  93. package/src/cli/pane-functions/access-gate.ts +22 -0
  94. package/src/cli/pane-functions/capabilities.ts +62 -4
  95. package/src/cli/pane-functions/catalog.ts +144 -39
  96. package/src/cli/pane-functions/data.ts +6 -5
  97. package/src/cli/pane-functions/discovery.ts +1 -1
  98. package/src/cli/pane-functions/dom.ts +3 -3
  99. package/src/cli/pane-functions/freshness.ts +93 -17
  100. package/src/cli/pane-functions/function-help.ts +20 -17
  101. package/src/cli/pane-functions/headless.ts +187 -40
  102. package/src/cli/pane-functions/index.ts +126 -12
  103. package/src/cli/pane-functions/options.ts +17 -3
  104. package/src/cli/pane-functions/report-notices.ts +17 -3
  105. package/src/cli/pane-functions/resolver.ts +74 -18
  106. package/src/cli/pane-functions/screenshot.ts +126 -23
  107. package/src/cli/pane-functions/shot-options.ts +68 -0
  108. package/src/cli/perpetual-contract.ts +3 -1
  109. package/src/cli/report-tables.ts +21 -6
  110. package/src/cli/result.ts +2 -0
  111. package/src/cli/series-search.ts +6 -1
  112. package/src/cli/staged-tickers.ts +5 -0
  113. package/src/cli/statement-filings.ts +261 -0
  114. package/src/cli/symbol-args.ts +47 -8
  115. package/src/cli/symbol-list.ts +9 -2
  116. package/src/cli/symbol-rows.ts +269 -29
  117. package/src/cli/ticker-resolution.ts +148 -35
  118. package/src/cli/treasury-yields.ts +86 -0
  119. package/src/cli/types.ts +3 -0
  120. package/src/cli/uncovered-instrument.ts +20 -0
  121. package/src/cli/unknown-command.ts +18 -0
  122. package/src/components/chart/composite/axis-overlays.tsx +16 -9
  123. package/src/components/chart/composite/composite-chart.tsx +163 -23
  124. package/src/components/chart/composite/downsample.ts +19 -3
  125. package/src/components/chart/composite/format.ts +13 -0
  126. package/src/components/chart/composite/legend.tsx +161 -68
  127. package/src/components/chart/composite/panel-bitmap.ts +8 -2
  128. package/src/components/chart/composite/panel-labels.ts +38 -0
  129. package/src/components/chart/composite/panel-series.ts +1 -0
  130. package/src/components/chart/composite/panel-surface.tsx +28 -10
  131. package/src/components/chart/composite/price-axis-labels.tsx +16 -3
  132. package/src/components/chart/composite/scene.ts +60 -2
  133. package/src/components/chart/composite/series-axis-tags.tsx +67 -0
  134. package/src/components/chart/composite/toolbar.tsx +12 -7
  135. package/src/components/chart/composite/tools.ts +2 -2
  136. package/src/components/chart/composite/types.ts +34 -0
  137. package/src/components/chart/composite/use-composite-chart-keyboard.ts +28 -1
  138. package/src/components/chart/core/view-reset.ts +46 -0
  139. package/src/components/chart/curve/curve-surface.tsx +1 -1
  140. package/src/components/chart/static/series.ts +39 -0
  141. package/src/components/chart/static/trail-chart-surface.tsx +2 -1
  142. package/src/components/command-bar/commands/collection-list.ts +45 -15
  143. package/src/components/command-bar/commands/collection.ts +11 -4
  144. package/src/components/command-bar/commands/direct/index.ts +1 -1
  145. package/src/components/command-bar/commands/registry.ts +2 -2
  146. package/src/components/command-bar/list/badge.ts +4 -3
  147. package/src/components/command-bar/list/model.ts +12 -0
  148. package/src/components/command-bar/list/view.tsx +1 -1
  149. package/src/components/command-bar/pane-templates/workflow.ts +5 -0
  150. package/src/components/command-bar/panel/index.tsx +19 -8
  151. package/src/components/command-bar/panel/native-surface.ts +6 -4
  152. package/src/components/command-bar/panel/prompt-example.ts +22 -0
  153. package/src/components/command-bar/routes/root/command-items.ts +1 -1
  154. package/src/components/command-bar/routes/root/pick-prefetch.ts +38 -0
  155. package/src/components/command-bar/routes/root/provider-search.ts +9 -9
  156. package/src/components/command-bar/routes/root/results.ts +13 -0
  157. package/src/components/command-bar/routes/root/runtime.ts +3 -0
  158. package/src/components/command-bar/routes/root/shortcut-feedback.ts +3 -1
  159. package/src/components/command-bar/routes/root/shortcut-items.ts +1 -1
  160. package/src/components/command-bar/routes/root/start-here.ts +90 -0
  161. package/src/components/command-bar/routes/ticker-search/actions.ts +34 -0
  162. package/src/components/command-bar/routes/ticker-search/results.ts +42 -3
  163. package/src/components/command-bar/routes/ticker-search/route.ts +3 -10
  164. package/src/components/command-bar/surface/index.tsx +5 -0
  165. package/src/components/command-bar/theme-picker.tsx +3 -1
  166. package/src/components/command-bar/workflow/builtin.ts +5 -1
  167. package/src/components/command-bar/workflow/collection-actions.ts +23 -13
  168. package/src/components/command-bar/workflow/ops.ts +25 -3
  169. package/src/components/command-bar/workflow/pane-reuse.ts +3 -2
  170. package/src/{plugins/builtin/portfolio-list/command-bar.ts → components/command-bar/workflow/portfolio-position.ts} +42 -9
  171. package/src/components/command-bar/workflow/tickers.ts +7 -5
  172. package/src/components/feedback-dialog.tsx +1 -1
  173. package/src/components/form-modal/broker-step.tsx +7 -63
  174. package/src/components/form-modal/content.tsx +7 -2
  175. package/src/components/form-modal/field-row.tsx +6 -8
  176. package/src/components/form-modal/host.tsx +3 -3
  177. package/src/components/form-modal/model.ts +3 -0
  178. package/src/components/form-modal/routes.ts +17 -2
  179. package/src/components/index.ts +6 -6
  180. package/src/components/input-search-bar.tsx +43 -6
  181. package/src/components/layout/detached-pane-shell.tsx +0 -1
  182. package/src/components/layout/floating-pane.tsx +0 -1
  183. package/src/components/layout/header.tsx +8 -7
  184. package/src/components/layout/pane/content.tsx +11 -8
  185. package/src/components/layout/pane/footer/index.tsx +7 -4
  186. package/src/components/layout/pane/footer/model.ts +28 -2
  187. package/src/components/layout/pane/header.tsx +9 -19
  188. package/src/components/layout/pane/index.tsx +0 -1
  189. package/src/components/layout/pane/instrument-coverage-gate.tsx +57 -0
  190. package/src/components/layout/pane/pane-tabs.tsx +4 -3
  191. package/src/components/layout/pane/sizing.ts +9 -0
  192. package/src/components/layout/pane/ticker-fate-gate.tsx +62 -0
  193. package/src/components/layout/shell/pane/capture.ts +44 -20
  194. package/src/components/layout/status-bar.tsx +3 -6
  195. package/src/components/markdown-text.tsx +17 -2
  196. package/src/components/market-board/index.tsx +19 -8
  197. package/src/components/metric-treemap/heat-surface.tsx +2 -7
  198. package/src/components/onboarding/account-step/qr-panel.tsx +5 -2
  199. package/src/components/onboarding/onboarding-frame.tsx +24 -21
  200. package/src/components/onboarding/portfolio-step/positions-panel.tsx +20 -10
  201. package/src/components/onboarding/wizard-model.ts +1 -1
  202. package/src/components/onboarding/wizard-positions.ts +56 -19
  203. package/src/components/pane-settings-dialog/desktop.tsx +12 -50
  204. package/src/components/pane-settings-dialog/field-dialogs.tsx +1 -1
  205. package/src/components/price-performance.tsx +18 -2
  206. package/src/components/reader/article-reader.tsx +11 -10
  207. package/src/components/reader/detail-reader.tsx +9 -5
  208. package/src/components/reader/reader-text.tsx +51 -24
  209. package/src/components/sign-in-code-panel.tsx +129 -75
  210. package/src/components/ticker/badge/format.ts +64 -15
  211. package/src/components/ticker/badge/index.tsx +33 -11
  212. package/src/components/ticker/badge/list.tsx +4 -3
  213. package/src/components/ticker/badge/text.tsx +2 -2
  214. package/src/components/ticker/list-table-view.tsx +8 -1
  215. package/src/components/ui/action-row.tsx +5 -2
  216. package/src/components/ui/audio-player.tsx +70 -0
  217. package/src/components/ui/card.tsx +75 -0
  218. package/src/components/ui/data-table/index.tsx +4 -2
  219. package/src/components/ui/data-table/opentui/index.tsx +61 -20
  220. package/src/components/ui/data-table/opentui/model.ts +104 -0
  221. package/src/components/ui/data-table/types.ts +11 -0
  222. package/src/components/ui/detail-scroll-body.tsx +1 -1
  223. package/src/components/ui/dialog-actions.tsx +1 -21
  224. package/src/components/ui/display.tsx +13 -5
  225. package/src/components/ui/external-link.tsx +4 -2
  226. package/src/components/ui/fields.tsx +12 -0
  227. package/src/components/ui/figure.tsx +5 -3
  228. package/src/components/ui/frame.tsx +40 -6
  229. package/src/components/ui/icon.tsx +4 -0
  230. package/src/components/ui/index.ts +4 -1
  231. package/src/components/ui/inline-quick-add.tsx +4 -1
  232. package/src/components/ui/list-view.tsx +8 -0
  233. package/src/components/ui/prose.tsx +97 -25
  234. package/src/components/ui/query-bar-keys.tsx +32 -6
  235. package/src/components/ui/query-bar.tsx +35 -4
  236. package/src/components/ui/quote.ts +42 -0
  237. package/src/components/ui/range-track.tsx +15 -2
  238. package/src/components/ui/reveal-in-scroll-box.ts +21 -3
  239. package/src/components/ui/select-button.tsx +38 -3
  240. package/src/components/ui/status.tsx +73 -4
  241. package/src/components/ui/table-layout.ts +20 -0
  242. package/src/components/ui/windowed-list.tsx +27 -0
  243. package/src/components/use-pinned-moment.ts +19 -0
  244. package/src/core/app-runtime.ts +2 -2
  245. package/src/core/state/app/instrument.ts +18 -1
  246. package/src/core/state/app/layout.ts +6 -0
  247. package/src/core/state/app/state.ts +14 -2
  248. package/src/data/cached-query.ts +1 -1
  249. package/src/data/config/chart-settings.ts +3 -1
  250. package/src/data/config/home.ts +4 -1
  251. package/src/data/config/store/node.ts +9 -4
  252. package/src/data/config/store/normalize.ts +9 -0
  253. package/src/data/json-storage.ts +6 -3
  254. package/src/data/json-ticker-repository.ts +3 -1
  255. package/src/data/plugin-cache.ts +5 -1
  256. package/src/data/sqlite/json.ts +3 -1
  257. package/src/data/ticker-repository.ts +5 -2
  258. package/src/docs/snapshot.json +248 -5
  259. package/src/feedback/diagnostics.ts +2 -6
  260. package/src/i18n/es.ts +86 -6
  261. package/src/i18n/index.ts +3 -9
  262. package/src/i18n/ja.ts +86 -6
  263. package/src/i18n/ko.ts +86 -6
  264. package/src/i18n/zh-cn.ts +86 -6
  265. package/src/i18n/zh-tw.ts +86 -6
  266. package/src/layout-marketplace/cloud.ts +16 -5
  267. package/src/layout-marketplace/gallery-desktop.tsx +8 -4
  268. package/src/layout-marketplace/gallery.tsx +4 -4
  269. package/src/layout-marketplace/linked-sync.ts +9 -3
  270. package/src/layout-marketplace/linked.ts +24 -3
  271. package/src/layout-marketplace/model.ts +39 -4
  272. package/src/market-data/bars-per-year.ts +43 -0
  273. package/src/market-data/bond-funds.ts +85 -0
  274. package/src/market-data/coordinator/auxiliary.ts +5 -2
  275. package/src/market-data/coordinator/index.ts +39 -5
  276. package/src/market-data/futures-contract.ts +155 -5
  277. package/src/market-data/hooks.tsx +77 -12
  278. package/src/market-data/market/bar-period.ts +107 -0
  279. package/src/market-data/market/format.ts +18 -14
  280. package/src/market-data/market/freshness.ts +29 -4
  281. package/src/market-data/market/index-level.ts +51 -0
  282. package/src/market-data/market/status.ts +152 -13
  283. package/src/market-data/model-dividend-yield.ts +117 -0
  284. package/src/market-data/quotes/freshness.ts +30 -1
  285. package/src/{plugins/builtin/portfolio-list → market-data/quotes}/live-valuation.ts +52 -6
  286. package/src/market-data/quotes/regular-session-valuation.ts +32 -1
  287. package/src/market-data/realized-volatility.ts +16 -7
  288. package/src/market-data/tax-equivalent.ts +344 -0
  289. package/src/news/aggregator.ts +4 -2
  290. package/src/notifications/notification-log.ts +5 -3
  291. package/src/plugins/auto-update-node.ts +1 -0
  292. package/src/plugins/builtin/account-management/footer.ts +1 -1
  293. package/src/plugins/builtin/account-management/keyboard.ts +3 -0
  294. package/src/plugins/builtin/account-management/model.ts +1 -0
  295. package/src/plugins/builtin/account-management/pane.tsx +71 -19
  296. package/src/plugins/builtin/account-management/trial-cancel.ts +40 -0
  297. package/src/plugins/builtin/alerts/cli.ts +7 -18
  298. package/src/plugins/builtin/alerts/constants.ts +8 -0
  299. package/src/plugins/builtin/alerts/event-rows.ts +16 -0
  300. package/src/plugins/builtin/alerts/events-pane.tsx +2 -14
  301. package/src/plugins/builtin/alerts/headless.ts +182 -0
  302. package/src/plugins/builtin/alerts/index.tsx +3 -0
  303. package/src/plugins/builtin/alerts/pane.tsx +1 -7
  304. package/src/plugins/builtin/alerts/storage.ts +17 -1
  305. package/src/plugins/builtin/analytics/index.tsx +6 -1
  306. package/src/plugins/builtin/analytics/metrics.ts +55 -13
  307. package/src/plugins/builtin/analytics/risk-headless.ts +26 -7
  308. package/src/plugins/builtin/analytics/risk-math.ts +83 -0
  309. package/src/plugins/builtin/analytics/risk-model.ts +171 -19
  310. package/src/plugins/builtin/analytics/risk-pane.tsx +17 -12
  311. package/src/plugins/builtin/analytics/sector-model.ts +14 -3
  312. package/src/plugins/builtin/awards/headless.ts +6 -5
  313. package/src/plugins/builtin/awards/index.tsx +1 -1
  314. package/src/plugins/builtin/backtest/client.ts +38 -8
  315. package/src/plugins/builtin/backtest/engine.ts +25 -13
  316. package/src/plugins/builtin/backtest/export.ts +27 -0
  317. package/src/plugins/builtin/backtest/format.ts +19 -3
  318. package/src/plugins/builtin/backtest/headless.ts +42 -28
  319. package/src/plugins/builtin/backtest/index.tsx +3 -0
  320. package/src/plugins/builtin/backtest/pane.tsx +39 -10
  321. package/src/plugins/builtin/backtest/report.ts +160 -0
  322. package/src/plugins/builtin/backtest/rules.ts +2 -0
  323. package/src/plugins/builtin/backtest/window.ts +112 -0
  324. package/src/plugins/builtin/bond-calculator/headless.ts +3 -2
  325. package/src/plugins/builtin/broker-manager/add-flow.tsx +4 -4
  326. package/src/plugins/builtin/builtin-plugin-meta.ts +0 -1
  327. package/src/plugins/builtin/catalysts/headless.ts +24 -13
  328. package/src/plugins/builtin/catalysts/index.tsx +4 -2
  329. package/src/plugins/builtin/catalysts/model.ts +18 -1
  330. package/src/plugins/builtin/catalysts/pane.tsx +2 -2
  331. package/src/plugins/builtin/cds/client.ts +28 -5
  332. package/src/plugins/builtin/cds/headless.ts +183 -31
  333. package/src/plugins/builtin/cds/index.tsx +1 -1
  334. package/src/plugins/builtin/cds/model.ts +229 -53
  335. package/src/plugins/builtin/cds/pane.tsx +82 -26
  336. package/src/plugins/builtin/central-bank-rates/headless.ts +1 -1
  337. package/src/plugins/builtin/chart-composer/catalog-inventory.ts +39 -1
  338. package/src/plugins/builtin/chart-composer/chart-spec-edit.ts +77 -0
  339. package/src/plugins/builtin/chart-composer/chart-spec.ts +15 -0
  340. package/src/plugins/builtin/chart-composer/data-catalog-pane.tsx +22 -2
  341. package/src/plugins/builtin/chart-composer/editor/controller.ts +14 -10
  342. package/src/plugins/builtin/chart-composer/editor/desktop-view.tsx +2 -2
  343. package/src/plugins/builtin/chart-composer/formula.ts +233 -0
  344. package/src/plugins/builtin/chart-composer/headless-schema.ts +10 -2
  345. package/src/plugins/builtin/chart-composer/headless.ts +117 -15
  346. package/src/plugins/builtin/chart-composer/index.tsx +73 -15
  347. package/src/plugins/builtin/chart-composer/pane.tsx +86 -23
  348. package/src/plugins/builtin/chart-composer/presets.ts +165 -8
  349. package/src/plugins/builtin/chart-composer/quick-add.tsx +9 -2
  350. package/src/plugins/builtin/chart-composer/series-catalog.ts +85 -16
  351. package/src/plugins/builtin/chart-composer/series-expression.ts +10 -8
  352. package/src/plugins/builtin/chart-composer/series-listings.ts +178 -0
  353. package/src/plugins/builtin/chart-composer/session-range.ts +87 -0
  354. package/src/plugins/builtin/chart-composer/settings.ts +16 -4
  355. package/src/plugins/builtin/chart-composer/studies.ts +1 -1
  356. package/src/plugins/builtin/chat/attachments/desktop.tsx +4 -1
  357. package/src/plugins/builtin/chat/content/channel-navigation.ts +17 -6
  358. package/src/plugins/builtin/chat/content/composer-runtime.ts +49 -14
  359. package/src/plugins/builtin/chat/content/composer.tsx +22 -1
  360. package/src/plugins/builtin/chat/content/index.tsx +47 -10
  361. package/src/plugins/builtin/chat/content/layout-metrics.ts +3 -0
  362. package/src/plugins/builtin/chat/content/mentions.ts +50 -21
  363. package/src/plugins/builtin/chat/content/scroll.ts +12 -5
  364. package/src/plugins/builtin/chat/content/shortcuts.ts +32 -13
  365. package/src/plugins/builtin/chat/content/snapshot.ts +40 -6
  366. package/src/plugins/builtin/chat/content/transcript.tsx +48 -37
  367. package/src/plugins/builtin/chat/content/whole-message-copy.ts +44 -2
  368. package/src/plugins/builtin/chat/controller/index.ts +68 -17
  369. package/src/plugins/builtin/chat/controller/mention-candidates.ts +104 -0
  370. package/src/plugins/builtin/chat/controller/realtime.ts +9 -0
  371. package/src/plugins/builtin/chat/controller/state.ts +10 -0
  372. package/src/plugins/builtin/chat/controller/view.ts +2 -0
  373. package/src/plugins/builtin/chat/conversation-recency.ts +73 -0
  374. package/src/plugins/builtin/chat/conversations.ts +12 -5
  375. package/src/plugins/builtin/chat/ghost-user.ts +11 -3
  376. package/src/plugins/builtin/chat/layout.ts +25 -5
  377. package/src/plugins/builtin/chat/message/desktop.tsx +15 -5
  378. package/src/plugins/builtin/chat/message/header.tsx +26 -4
  379. package/src/plugins/builtin/chat/message/pane-chip.tsx +131 -35
  380. package/src/plugins/builtin/chat/message/render-state.ts +28 -1
  381. package/src/plugins/builtin/chat/message/terminal.tsx +9 -3
  382. package/src/plugins/builtin/chat/pane-links/composer.ts +87 -0
  383. package/src/plugins/builtin/chat/pane-links/model.ts +1 -1
  384. package/src/plugins/builtin/chat/share/flow.tsx +9 -73
  385. package/src/plugins/builtin/chat/sidebar-rows.ts +18 -5
  386. package/src/plugins/builtin/chat/sidebar.tsx +6 -1
  387. package/src/plugins/builtin/cloud/askg/controller.ts +5 -3
  388. package/src/plugins/builtin/cloud/askg/executor.ts +3 -1
  389. package/src/plugins/builtin/cloud/askg/lock-note.ts +16 -0
  390. package/src/plugins/builtin/cloud/askg/manifest.ts +4 -3
  391. package/src/plugins/builtin/cloud/askg/pane.tsx +6 -2
  392. package/src/plugins/builtin/cloud/auth-actions.tsx +4 -2
  393. package/src/plugins/builtin/cloud/company-picker.tsx +21 -26
  394. package/src/plugins/builtin/cloud/mcp-connect/dialog.tsx +5 -3
  395. package/src/plugins/builtin/cloud/plugin.tsx +2 -0
  396. package/src/plugins/builtin/cloud/team/module.tsx +5 -1
  397. package/src/plugins/builtin/cloud/team/pane.tsx +11 -4
  398. package/src/plugins/builtin/cloud/team/views.ts +11 -4
  399. package/src/plugins/builtin/cloud/terminal-relay/engine.ts +9 -4
  400. package/src/plugins/builtin/cloud/terminal-relay/manifest.ts +16 -5
  401. package/src/plugins/builtin/cloud/terminal-relay/prompts.tsx +3 -2
  402. package/src/plugins/builtin/cloud/thesis/detail.tsx +2 -1
  403. package/src/plugins/builtin/cloud/thesis/exposure.ts +3 -0
  404. package/src/plugins/builtin/cloud/thesis/prompts.tsx +3 -2
  405. package/src/plugins/builtin/cloud/thesis/ticker-tab.tsx +2 -1
  406. package/src/plugins/builtin/cloud/trial-offer-status-widget.tsx +2 -1
  407. package/src/plugins/builtin/cloud/verification-status-widget.tsx +2 -1
  408. package/src/plugins/builtin/commodities-energy/index.tsx +31 -9
  409. package/src/plugins/builtin/commodities-energy/view-state.ts +11 -0
  410. package/src/plugins/builtin/commodity-balances/client.ts +51 -193
  411. package/src/plugins/builtin/commodity-balances/headless.ts +10 -3
  412. package/src/plugins/builtin/commodity-balances/model.ts +5 -180
  413. package/src/plugins/builtin/commodity-balances/pane.tsx +3 -0
  414. package/src/plugins/builtin/company-attention/headless.ts +15 -7
  415. package/src/plugins/builtin/company-attention/index.tsx +1 -1
  416. package/src/plugins/builtin/company-attention/model.ts +49 -4
  417. package/src/plugins/builtin/company-attention/pane.tsx +11 -9
  418. package/src/plugins/builtin/company-kpis/headless.ts +4 -3
  419. package/src/plugins/builtin/company-kpis/index.tsx +2 -2
  420. package/src/plugins/builtin/company-kpis/pane.tsx +9 -3
  421. package/src/plugins/builtin/congress-trades/headless.ts +23 -2
  422. package/src/plugins/builtin/correlation/relationship/pane.tsx +18 -46
  423. package/src/plugins/builtin/cot/headless.ts +5 -2
  424. package/src/plugins/builtin/credit-boards/cdx-pane.tsx +41 -13
  425. package/src/plugins/builtin/credit-boards/client.ts +9 -2
  426. package/src/plugins/builtin/credit-boards/headless.ts +93 -27
  427. package/src/plugins/builtin/credit-boards/index.tsx +15 -4
  428. package/src/plugins/builtin/credit-boards/model.ts +105 -6
  429. package/src/plugins/builtin/credit-boards/sovr-pane.tsx +14 -3
  430. package/src/plugins/builtin/credit-documents/detail.tsx +2 -1
  431. package/src/plugins/builtin/credit-documents/index.tsx +3 -0
  432. package/src/plugins/builtin/credit-documents/model.ts +3 -10
  433. package/src/plugins/builtin/crypto-board/client.ts +152 -2
  434. package/src/plugins/builtin/crypto-board/headless.ts +138 -19
  435. package/src/plugins/builtin/crypto-board/index.tsx +5 -3
  436. package/src/plugins/builtin/crypto-board/model.ts +210 -12
  437. package/src/plugins/builtin/crypto-board/pane.tsx +148 -9
  438. package/src/plugins/builtin/crypto-board/series.ts +52 -1
  439. package/src/plugins/builtin/crypto-board/supply.ts +123 -0
  440. package/src/plugins/builtin/custom-view/index.tsx +1 -1
  441. package/src/plugins/builtin/custom-view/loader.ts +57 -7
  442. package/src/plugins/builtin/custom-view/sources.ts +146 -0
  443. package/src/plugins/builtin/custom-view/view-spec.ts +37 -1
  444. package/src/plugins/builtin/debt-maturities/client.ts +54 -1
  445. package/src/plugins/builtin/debt-maturities/headless.ts +27 -3
  446. package/src/plugins/builtin/debt-maturities/index.tsx +2 -0
  447. package/src/plugins/builtin/debt-maturities/model.ts +58 -13
  448. package/src/plugins/builtin/debt-maturities/pane.tsx +47 -7
  449. package/src/plugins/builtin/dividend-yield/client.ts +42 -36
  450. package/src/plugins/builtin/dividend-yield/headless.ts +113 -18
  451. package/src/plugins/builtin/dividend-yield/index.tsx +5 -2
  452. package/src/plugins/builtin/dividend-yield/pane.tsx +37 -13
  453. package/src/plugins/builtin/dividend-yield/provider-client.ts +7 -3
  454. package/src/plugins/builtin/dividend-yield/ranking.ts +187 -0
  455. package/src/plugins/builtin/dividend-yield/reference-price.ts +28 -5
  456. package/src/plugins/builtin/dividend-yield/types.ts +6 -1
  457. package/src/plugins/builtin/dividend-yield/view.ts +1 -1
  458. package/src/plugins/builtin/docs/blocks.tsx +54 -8
  459. package/src/plugins/builtin/docs/pane.tsx +8 -13
  460. package/src/plugins/builtin/earnings/board-model.ts +33 -3
  461. package/src/plugins/builtin/earnings/board-table.ts +59 -14
  462. package/src/plugins/builtin/earnings/board.tsx +36 -3
  463. package/src/plugins/builtin/earnings/headless.ts +27 -7
  464. package/src/plugins/builtin/earnings/history-model.ts +9 -1
  465. package/src/plugins/builtin/earnings/history-table.ts +16 -5
  466. package/src/plugins/builtin/earnings/history.tsx +40 -10
  467. package/src/plugins/builtin/earnings/index.tsx +3 -1
  468. package/src/plugins/builtin/earnings/no-earnings.ts +52 -0
  469. package/src/plugins/builtin/earnings-calls/data.ts +51 -0
  470. package/src/plugins/builtin/earnings-calls/headless.ts +7 -0
  471. package/src/plugins/builtin/earnings-calls/index.tsx +1 -0
  472. package/src/plugins/builtin/earnings-calls/model.ts +97 -0
  473. package/src/plugins/builtin/earnings-calls/pane.tsx +107 -7
  474. package/src/plugins/builtin/earnings-calls/transcript-view.tsx +140 -22
  475. package/src/plugins/builtin/earnings-calls/use-call-playback.ts +194 -0
  476. package/src/plugins/builtin/econ/calendar-model.ts +22 -0
  477. package/src/plugins/builtin/econ/calendar-source.ts +35 -0
  478. package/src/plugins/builtin/econ/index.tsx +40 -8
  479. package/src/plugins/builtin/econ-statistics/defs.ts +7 -0
  480. package/src/plugins/builtin/econ-statistics/detail.tsx +11 -1
  481. package/src/plugins/builtin/econ-statistics/headless.ts +31 -5
  482. package/src/plugins/builtin/econ-statistics/pane.tsx +5 -3
  483. package/src/plugins/builtin/econ-statistics/stats.ts +10 -0
  484. package/src/plugins/builtin/econ-statistics/view.ts +23 -0
  485. package/src/plugins/builtin/equity-screener/client.ts +1 -1
  486. package/src/plugins/builtin/equity-screener/model.ts +46 -4
  487. package/src/plugins/builtin/equity-screener/pane.tsx +3 -0
  488. package/src/plugins/builtin/estimate-revisions/client.ts +32 -22
  489. package/src/plugins/builtin/estimate-revisions/headless.ts +1 -0
  490. package/src/plugins/builtin/estimate-revisions/index.tsx +1 -0
  491. package/src/plugins/builtin/estimate-revisions/pane.tsx +5 -3
  492. package/src/plugins/builtin/executives/index.tsx +1 -0
  493. package/src/plugins/builtin/exposure/editor.tsx +3 -3
  494. package/src/plugins/builtin/fear-greed/index.tsx +9 -0
  495. package/src/plugins/builtin/filing-events/index.tsx +1 -0
  496. package/src/plugins/builtin/futures/index.tsx +2 -2
  497. package/src/plugins/builtin/futures/model.ts +39 -25
  498. package/src/plugins/builtin/futures/series.ts +38 -1
  499. package/src/plugins/builtin/futures/table.tsx +1 -1
  500. package/src/plugins/builtin/futures/use-board-terms.ts +2 -2
  501. package/src/plugins/builtin/futures-curve/client.ts +4 -4
  502. package/src/plugins/builtin/futures-curve/headless.ts +24 -4
  503. package/src/plugins/builtin/futures-curve/index.tsx +2 -2
  504. package/src/plugins/builtin/futures-curve/model.ts +50 -9
  505. package/src/plugins/builtin/futures-curve/pane.tsx +14 -10
  506. package/src/plugins/builtin/help/index.tsx +55 -8
  507. package/src/plugins/builtin/help/shortcut-table.tsx +15 -2
  508. package/src/plugins/builtin/holders/headless.ts +12 -0
  509. package/src/plugins/builtin/insider/headless.ts +345 -5
  510. package/src/plugins/builtin/insider/index.tsx +304 -36
  511. package/src/plugins/builtin/insider/insiders.tsx +224 -0
  512. package/src/plugins/builtin/insider/signals-cells.tsx +52 -0
  513. package/src/plugins/builtin/insider/signals-client.ts +193 -0
  514. package/src/plugins/builtin/insider/signals-model.ts +718 -0
  515. package/src/plugins/builtin/insider/signals.tsx +376 -0
  516. package/src/plugins/builtin/ipo-calendar/headless.ts +17 -7
  517. package/src/plugins/builtin/ipo-calendar/index.tsx +23 -3
  518. package/src/plugins/builtin/ipo-calendar/model.ts +84 -36
  519. package/src/plugins/builtin/ipo-calendar/pane.tsx +20 -8
  520. package/src/plugins/builtin/iv-history/client.ts +41 -2
  521. package/src/plugins/builtin/iv-history/headless.ts +26 -16
  522. package/src/plugins/builtin/iv-history/screen-pane.tsx +25 -7
  523. package/src/plugins/builtin/jobs/headless.ts +1 -0
  524. package/src/plugins/builtin/jobs/index.tsx +1 -0
  525. package/src/plugins/builtin/jodi/client.ts +42 -205
  526. package/src/plugins/builtin/jodi/headless.ts +15 -4
  527. package/src/plugins/builtin/jodi/model.ts +18 -43
  528. package/src/plugins/builtin/jodi/pane.tsx +5 -0
  529. package/src/plugins/builtin/kelly-sizer/pane.tsx +1 -1
  530. package/src/plugins/builtin/kelly-sizer/portfolio.ts +1 -1
  531. package/src/plugins/builtin/market-heatmap/headless.ts +1 -0
  532. package/src/plugins/builtin/market-heatmap/portfolio.ts +3 -1
  533. package/src/plugins/builtin/market-movers/client.ts +32 -6
  534. package/src/plugins/builtin/market-movers/headless.ts +7 -2
  535. package/src/plugins/builtin/market-movers/model.ts +64 -3
  536. package/src/plugins/builtin/market-movers/screener.ts +20 -9
  537. package/src/plugins/builtin/market-valuation/detail.tsx +7 -2
  538. package/src/plugins/builtin/market-valuation/headless.ts +17 -4
  539. package/src/plugins/builtin/market-valuation/pane.tsx +8 -4
  540. package/src/plugins/builtin/market-valuation/view.ts +10 -0
  541. package/src/plugins/builtin/market-valuation/zone-scale/desktop.tsx +31 -57
  542. package/src/plugins/builtin/mna/distress/headless.ts +2 -1
  543. package/src/plugins/builtin/mna/headless.ts +14 -2
  544. package/src/plugins/builtin/mna/index.tsx +1 -0
  545. package/src/plugins/builtin/news/headless.ts +4 -0
  546. package/src/plugins/builtin/news/wire/news/footer.ts +5 -3
  547. package/src/plugins/builtin/news/wire/news/table.tsx +57 -11
  548. package/src/plugins/builtin/notes/cli.ts +8 -4
  549. package/src/plugins/builtin/notes/files.ts +66 -20
  550. package/src/plugins/builtin/notes/migration.ts +18 -6
  551. package/src/plugins/builtin/notes/owner.tsx +3 -2
  552. package/src/plugins/builtin/notes/quick-notes-pane.tsx +3 -2
  553. package/src/plugins/builtin/options-positioning/client.ts +10 -0
  554. package/src/plugins/builtin/options-positioning/headless.ts +88 -13
  555. package/src/plugins/builtin/options-positioning/index.tsx +2 -2
  556. package/src/plugins/builtin/options-positioning/model.ts +33 -0
  557. package/src/plugins/builtin/options-positioning/pane.tsx +38 -16
  558. package/src/plugins/builtin/options-scenario/charts.tsx +13 -4
  559. package/src/plugins/builtin/options-scenario/client.ts +114 -17
  560. package/src/plugins/builtin/options-scenario/collar.ts +141 -0
  561. package/src/plugins/builtin/options-scenario/csp.ts +1 -1
  562. package/src/plugins/builtin/options-scenario/freshness.ts +27 -0
  563. package/src/plugins/builtin/options-scenario/headless.ts +30 -12
  564. package/src/plugins/builtin/options-scenario/index.tsx +1 -1
  565. package/src/plugins/builtin/options-scenario/model.ts +55 -5
  566. package/src/plugins/builtin/options-scenario/pane.tsx +24 -5
  567. package/src/plugins/builtin/pe-band/index.tsx +1 -1
  568. package/src/plugins/builtin/pe-band/model.ts +1 -15
  569. package/src/plugins/builtin/perps/headless.ts +30 -13
  570. package/src/plugins/builtin/perps/model.ts +45 -3
  571. package/src/plugins/builtin/perps/pane.tsx +7 -7
  572. package/src/plugins/builtin/portfolio-list/cell-version.ts +10 -4
  573. package/src/plugins/builtin/portfolio-list/cli/bulk-symbols.ts +128 -14
  574. package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +144 -63
  575. package/src/plugins/builtin/portfolio-list/cli/render.ts +373 -48
  576. package/src/plugins/builtin/portfolio-list/cli/shared.ts +23 -9
  577. package/src/plugins/builtin/portfolio-list/cli/watchlist-command.ts +25 -35
  578. package/src/plugins/builtin/portfolio-list/grid.tsx +3 -1
  579. package/src/plugins/builtin/portfolio-list/headless.ts +161 -32
  580. package/src/plugins/builtin/portfolio-list/income.ts +296 -0
  581. package/src/plugins/builtin/portfolio-list/metrics.ts +2 -2
  582. package/src/plugins/builtin/portfolio-list/pane/futures-terms.ts +58 -0
  583. package/src/plugins/builtin/portfolio-list/pane/index.tsx +63 -14
  584. package/src/plugins/builtin/portfolio-list/pane/remove-ticker.ts +1 -1
  585. package/src/plugins/builtin/portfolio-list/pane/supplemental.ts +47 -28
  586. package/src/plugins/builtin/portfolio-list/quick-add/index.tsx +38 -8
  587. package/src/plugins/builtin/portfolio-list/quick-add/resolution.ts +12 -4
  588. package/src/plugins/builtin/portfolio-list/settings.ts +22 -0
  589. package/src/plugins/builtin/portfolio-list/since-last-seen.ts +197 -0
  590. package/src/plugins/builtin/portfolio-list/summary/index.tsx +26 -4
  591. package/src/plugins/builtin/portfolio-list/summary/totals.ts +32 -4
  592. package/src/plugins/builtin/portfolio-list/table.tsx +39 -7
  593. package/src/plugins/builtin/power/prices-headless.ts +2 -1
  594. package/src/plugins/builtin/realized-vol/chart-model.ts +29 -5
  595. package/src/plugins/builtin/realized-vol/charts.tsx +14 -8
  596. package/src/plugins/builtin/realized-vol/evidence.ts +2 -0
  597. package/src/plugins/builtin/realized-vol/headless.ts +6 -4
  598. package/src/plugins/builtin/realized-vol/model.ts +5 -1
  599. package/src/plugins/builtin/realized-vol/pane.tsx +31 -11
  600. package/src/plugins/builtin/realized-vol/settings.ts +1 -1
  601. package/src/plugins/builtin/research/analyst-headless.ts +4 -0
  602. package/src/plugins/builtin/research/corporate-actions-pane.tsx +16 -5
  603. package/src/plugins/builtin/research/event-model.ts +63 -51
  604. package/src/plugins/builtin/research/headless-schema.ts +1 -0
  605. package/src/plugins/builtin/research/headless.ts +4 -1
  606. package/src/plugins/builtin/research/index.tsx +3 -0
  607. package/src/plugins/builtin/research/relative-valuation-columns.ts +27 -5
  608. package/src/plugins/builtin/research/relative-valuation-headless.ts +2 -0
  609. package/src/plugins/builtin/revenue-breakdown/index.tsx +1 -0
  610. package/src/plugins/builtin/reverse-dcf/headless.ts +28 -9
  611. package/src/plugins/builtin/reverse-dcf/index.tsx +5 -2
  612. package/src/plugins/builtin/reverse-dcf/model.ts +87 -6
  613. package/src/plugins/builtin/reverse-dcf/pane.tsx +30 -7
  614. package/src/plugins/builtin/risk-factors/headless.ts +7 -0
  615. package/src/plugins/builtin/risk-factors/index.tsx +1 -0
  616. package/src/plugins/builtin/scanner/feed.ts +5 -3
  617. package/src/plugins/builtin/scanner/headless.ts +9 -57
  618. package/src/plugins/builtin/scanner/index.ts +1 -2
  619. package/src/plugins/builtin/sec/forms.ts +2 -6
  620. package/src/plugins/builtin/sec/fund-facts-view.tsx +53 -0
  621. package/src/plugins/builtin/sec/fund-facts.ts +328 -0
  622. package/src/plugins/builtin/sec/headless.ts +140 -44
  623. package/src/plugins/builtin/sec/index.tsx +95 -30
  624. package/src/plugins/builtin/sec/model.ts +2 -44
  625. package/src/plugins/builtin/shared/earnings-report.ts +48 -1
  626. package/src/plugins/builtin/shared/headless-options.ts +10 -0
  627. package/src/plugins/builtin/shared/history-span.ts +55 -0
  628. package/src/plugins/builtin/shared/locked-rows.tsx +3 -1
  629. package/src/plugins/builtin/shared/move-rank.ts +108 -0
  630. package/src/plugins/builtin/shared/report-freshness.ts +45 -20
  631. package/src/plugins/builtin/shared/scanner-capture.ts +95 -0
  632. package/src/plugins/builtin/shared/series-detail-chart.tsx +5 -2
  633. package/src/plugins/builtin/shared/series-list-detail.tsx +7 -3
  634. package/src/plugins/builtin/shared/ticker-surface.ts +16 -2
  635. package/src/plugins/builtin/shared/treasury-cutoffs.ts +15 -0
  636. package/src/plugins/builtin/shared/use-quote-board.ts +13 -5
  637. package/src/plugins/builtin/shared/volatility/live-session.ts +34 -0
  638. package/src/plugins/builtin/shared/volatility-indices.ts +32 -0
  639. package/src/plugins/builtin/short-interest/headless.ts +3 -0
  640. package/src/plugins/builtin/short-interest/watch-model.ts +2 -2
  641. package/src/plugins/builtin/social-mentions/client.ts +8 -1
  642. package/src/plugins/builtin/social-mentions/pane.tsx +8 -6
  643. package/src/plugins/builtin/supply-chain/client.ts +12 -3
  644. package/src/plugins/builtin/supply-chain/disclosure-quote.tsx +9 -5
  645. package/src/plugins/builtin/supply-chain/evidence.ts +3 -1
  646. package/src/plugins/builtin/supply-chain/flow-layout.ts +2 -1
  647. package/src/plugins/builtin/supply-chain/flow.tsx +23 -16
  648. package/src/plugins/builtin/supply-chain/graph-client.ts +8 -5
  649. package/src/plugins/builtin/supply-chain/graph-evidence.ts +1 -1
  650. package/src/plugins/builtin/supply-chain/graph-model.ts +10 -2
  651. package/src/plugins/builtin/supply-chain/graph-pane.tsx +9 -7
  652. package/src/plugins/builtin/supply-chain/graph.tsx +8 -6
  653. package/src/plugins/builtin/supply-chain/headless.ts +69 -27
  654. package/src/plugins/builtin/supply-chain/index.tsx +1 -1
  655. package/src/plugins/builtin/supply-chain/model.ts +76 -15
  656. package/src/plugins/builtin/supply-chain/pane.tsx +29 -15
  657. package/src/plugins/builtin/supply-chain/row-evidence.tsx +5 -4
  658. package/src/plugins/builtin/themes/headless.ts +15 -2
  659. package/src/plugins/builtin/themes/model.ts +2 -5
  660. package/src/plugins/builtin/thirteenf/api.ts +50 -2
  661. package/src/plugins/builtin/thirteenf/data.ts +250 -11
  662. package/src/plugins/builtin/thirteenf/headless.ts +311 -28
  663. package/src/plugins/builtin/thirteenf/index.tsx +4 -1
  664. package/src/plugins/builtin/thirteenf/model.ts +244 -19
  665. package/src/plugins/builtin/thirteenf/overlap-pane.tsx +133 -33
  666. package/src/plugins/builtin/thirteenf/overlap.ts +1 -1
  667. package/src/plugins/builtin/thirteenf/pane.tsx +24 -5
  668. package/src/plugins/builtin/thirteenf/report-notes.ts +78 -0
  669. package/src/plugins/builtin/thirteenf/types.ts +49 -0
  670. package/src/plugins/builtin/ticker-detail/data-panes/historical-prices.tsx +106 -24
  671. package/src/plugins/builtin/ticker-detail/data-panes/history-bars.ts +108 -0
  672. package/src/plugins/builtin/ticker-detail/data-panes/returns-pane.tsx +26 -8
  673. package/src/plugins/builtin/ticker-detail/financials/model.ts +2 -42
  674. package/src/plugins/builtin/ticker-detail/financials/tab.tsx +1 -1
  675. package/src/plugins/builtin/ticker-detail/headless-schema.ts +4 -2
  676. package/src/plugins/builtin/ticker-detail/headless.ts +109 -23
  677. package/src/plugins/builtin/ticker-detail/overview/components.tsx +27 -3
  678. package/src/plugins/builtin/ticker-detail/overview/dividend.ts +60 -0
  679. package/src/plugins/builtin/ticker-detail/overview/model.ts +46 -9
  680. package/src/plugins/builtin/ticker-detail/overview/pane.tsx +3 -0
  681. package/src/plugins/builtin/ticker-detail/overview-tab.tsx +37 -4
  682. package/src/plugins/builtin/ticker-detail/quote-monitor/card.tsx +18 -19
  683. package/src/plugins/builtin/time-sales/client.ts +7 -4
  684. package/src/plugins/builtin/time-sales/headless.ts +71 -22
  685. package/src/plugins/builtin/time-sales/model.ts +12 -0
  686. package/src/plugins/builtin/time-sales/pane.tsx +31 -7
  687. package/src/plugins/builtin/time-sales/window.ts +128 -0
  688. package/src/plugins/builtin/trace-bonds/client.ts +351 -33
  689. package/src/plugins/builtin/trace-bonds/headless.ts +60 -22
  690. package/src/plugins/builtin/trace-bonds/index.tsx +4 -2
  691. package/src/plugins/builtin/trace-bonds/model.ts +27 -25
  692. package/src/plugins/builtin/trace-bonds/pane.tsx +63 -45
  693. package/src/plugins/builtin/treasury-auctions/cache.ts +61 -15
  694. package/src/plugins/builtin/treasury-auctions/client.ts +45 -10
  695. package/src/plugins/builtin/treasury-auctions/headless.ts +35 -13
  696. package/src/plugins/builtin/treasury-auctions/index.tsx +5 -2
  697. package/src/plugins/builtin/treasury-auctions/model.ts +20 -16
  698. package/src/plugins/builtin/treasury-auctions/pane.tsx +29 -12
  699. package/src/plugins/builtin/vol-surface/charts.tsx +2 -1
  700. package/src/plugins/builtin/vol-surface/headless.ts +3 -2
  701. package/src/plugins/builtin/vol-surface/pane.tsx +2 -1
  702. package/src/plugins/builtin/vol-surface/stored.ts +4 -7
  703. package/src/plugins/builtin/volatility/chart-model.ts +16 -15
  704. package/src/plugins/builtin/volatility/charts.tsx +5 -5
  705. package/src/plugins/builtin/volatility/client.ts +73 -2
  706. package/src/plugins/builtin/volatility/evidence.ts +13 -14
  707. package/src/plugins/builtin/volatility/headless.ts +13 -7
  708. package/src/plugins/builtin/volatility/index.tsx +1 -1
  709. package/src/plugins/builtin/volatility/model.ts +104 -38
  710. package/src/plugins/builtin/volatility/pane.tsx +42 -24
  711. package/src/plugins/builtin/volatility/series.ts +22 -13
  712. package/src/plugins/builtin/world-venue-map/geo-series.ts +9 -0
  713. package/src/plugins/builtin/world-venue-map/headless.ts +25 -8
  714. package/src/plugins/builtin/world-venue-map/index.ts +16 -2
  715. package/src/plugins/builtin/world-venue-map/map.tsx +13 -17
  716. package/src/plugins/builtin/yield-curve/curves.ts +29 -5
  717. package/src/plugins/builtin/yield-curve/headless.ts +41 -8
  718. package/src/plugins/builtin/yield-curve/history.ts +5 -5
  719. package/src/plugins/builtin/yield-curve/index.tsx +30 -13
  720. package/src/plugins/compat.ts +3 -1
  721. package/src/plugins/dependencies.ts +8 -2
  722. package/src/plugins/host-link.ts +12 -5
  723. package/src/plugins/installer.ts +16 -7
  724. package/src/plugins/loader.ts +9 -2
  725. package/src/plugins/marketplace/activation.ts +10 -4
  726. package/src/plugins/registry/host-actions.ts +3 -0
  727. package/src/plugins/registry/index.ts +3 -1
  728. package/src/{plugins/builtin/portfolio-list → portfolio}/allocation.ts +82 -15
  729. package/src/{plugins/builtin/portfolio-list → portfolio}/column-values.ts +143 -55
  730. package/src/portfolio/futures-positions.ts +213 -0
  731. package/src/portfolio/futures-terms.ts +75 -0
  732. package/src/portfolio/manual-lots.ts +78 -0
  733. package/src/{plugins/builtin/portfolio-list → portfolio}/mutations.ts +59 -15
  734. package/src/portfolio/position-metrics.ts +44 -10
  735. package/src/portfolio/valuation-basis.ts +34 -24
  736. package/src/public/__snapshots__/public-api.test.ts.snap +6 -0
  737. package/src/public/time-series.ts +2 -1
  738. package/src/remote/confirm-change.tsx +2 -1
  739. package/src/remote/controller.ts +27 -7
  740. package/src/remote/schema.ts +25 -9
  741. package/src/remote/server.ts +1 -1
  742. package/src/remote/watchlist.ts +9 -1
  743. package/src/renderers/cloudflare/http-proxy.ts +21 -13
  744. package/src/renderers/dom/data-table/row.tsx +1 -1
  745. package/src/renderers/dom/desktop/audio-player.tsx +312 -0
  746. package/src/renderers/dom/desktop/control-styles.ts +17 -82
  747. package/src/renderers/dom/desktop/controls.tsx +39 -63
  748. package/src/renderers/dom/desktop/dialog-actions.tsx +13 -53
  749. package/src/renderers/dom/desktop/icons.tsx +8 -0
  750. package/src/renderers/dom/desktop/list-view.tsx +6 -6
  751. package/src/renderers/dom/desktop/popover.tsx +0 -3
  752. package/src/renderers/dom/desktop/query-bar.tsx +7 -5
  753. package/src/renderers/dom/desktop/select-field.tsx +9 -8
  754. package/src/renderers/dom/desktop/stack-header.ts +3 -0
  755. package/src/renderers/dom/dom-ui-host.tsx +5 -2
  756. package/src/renderers/dom/host/chart-surface.tsx +3 -3
  757. package/src/renderers/dom/host/size-observer.ts +33 -4
  758. package/src/renderers/dom/host/surface-3d.tsx +3 -2
  759. package/src/renderers/dom/host/surface-fit.ts +4 -1
  760. package/src/renderers/dom/host/tabs.tsx +22 -132
  761. package/src/renderers/dom/styles.css +358 -160
  762. package/src/renderers/dom/windowed-list.tsx +201 -0
  763. package/src/renderers/dom/windowed-rows.ts +65 -0
  764. package/src/renderers/electrobun/bun/core-capabilities.ts +1 -1
  765. package/src/renderers/electrobun/bun/desktop/backend-requests.ts +2 -9
  766. package/src/renderers/electrobun/bun/desktop/backend.ts +1 -1
  767. package/src/renderers/electrobun/bun/desktop/http-stream.ts +21 -6
  768. package/src/renderers/electrobun/bun/desktop/initialization.ts +1 -0
  769. package/src/renderers/electrobun/bun/desktop/state-broadcaster.ts +43 -1
  770. package/src/renderers/electrobun/bun/desktop/update.ts +21 -6
  771. package/src/renderers/electrobun/bun/desktop/workspace/requests.ts +5 -1
  772. package/src/renderers/electrobun/shared/protocol.ts +4 -2
  773. package/src/renderers/electrobun/shared/rpc-codec.ts +7 -0
  774. package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +21 -17
  775. package/src/renderers/electrobun/view/cli-pane-shot-frame.tsx +3 -3
  776. package/src/renderers/electrobun/view/desktop/window/bridge.ts +6 -8
  777. package/src/renderers/electrobun/view/desktop/window/snapshot.ts +18 -0
  778. package/src/renderers/electrobun/view/http-fetch.ts +12 -1
  779. package/src/series/capability.ts +1 -0
  780. package/src/series/files.ts +9 -3
  781. package/src/series/registry.ts +40 -14
  782. package/src/series/resolve.ts +121 -18
  783. package/src/series/standalone.ts +3 -2
  784. package/src/series/types.ts +55 -1
  785. package/src/series/validate.ts +39 -0
  786. package/src/shares/api.ts +26 -7
  787. package/src/shares/bug-report-dialog.tsx +2 -2
  788. package/src/shares/bug-report-flow.tsx +4 -7
  789. package/src/shares/capture-flow.ts +5 -4
  790. package/src/shares/capture-preview.tsx +2 -2
  791. package/src/shares/chat.ts +7 -27
  792. package/src/shares/flow.tsx +86 -40
  793. package/src/shares/location.ts +1 -3
  794. package/src/shares/pane-image.ts +11 -9
  795. package/src/shares/pane.ts +5 -2
  796. package/src/shares/payload.ts +1 -1
  797. package/src/shares/personal-pane.ts +3 -3
  798. package/src/shares/portable-layout.ts +9 -2
  799. package/src/shares/ready.ts +42 -0
  800. package/src/shares/test-harness.ts +62 -0
  801. package/src/sources/gloomberb-cloud/batched-lookups.ts +73 -0
  802. package/src/sources/gloomberb-cloud/index.ts +64 -12
  803. package/src/sources/gloomberb-cloud/normalizers.ts +31 -2
  804. package/src/sources/gloomberb-cloud/perpetuals.ts +20 -1
  805. package/src/sources/history-omitted.ts +34 -0
  806. package/src/sources/history-result.ts +3 -0
  807. package/src/sources/history-retention.ts +1 -1
  808. package/src/sources/listing-symbols.ts +8 -4
  809. package/src/sources/provider-errors.ts +43 -1
  810. package/src/sources/provider-router/batches.ts +3 -2
  811. package/src/sources/provider-router/cache.ts +2 -1
  812. package/src/sources/provider-router/cached-routes.ts +9 -3
  813. package/src/sources/provider-router/history.ts +9 -8
  814. package/src/sources/provider-router/index.ts +18 -3
  815. package/src/sources/provider-router/primary.ts +5 -4
  816. package/src/sources/provider-router/quote-route.ts +3 -1
  817. package/src/sources/provider-router/routing.ts +2 -1
  818. package/src/sources/provider-router/search.ts +47 -13
  819. package/src/sources/provider-router/streaming.ts +7 -4
  820. package/src/sources/sec-edgar.ts +1 -3
  821. package/src/state/app/context/index.tsx +9 -0
  822. package/src/state/app/tab-cursor.ts +222 -0
  823. package/src/state/hooks/quote-streaming.ts +3 -2
  824. package/src/state/hooks/session-snapshot.ts +3 -2
  825. package/src/state/persist-scheduler.ts +12 -4
  826. package/src/sync/controller.ts +22 -1
  827. package/src/sync/core-contributors.ts +264 -74
  828. package/src/team/collections-sync.ts +14 -4
  829. package/src/team/collections.ts +40 -11
  830. package/src/team/store.ts +5 -4
  831. package/src/telemetry/attention-counts.ts +8 -2
  832. package/src/telemetry/crash-reports-dom.ts +3 -0
  833. package/src/telemetry/crash-reports-node.ts +7 -4
  834. package/src/telemetry/crash-reports.ts +11 -11
  835. package/src/telemetry/usage-counts.ts +16 -12
  836. package/src/test-support/config-store.ts +31 -0
  837. package/src/test-support/moved-symbols.ts +64 -0
  838. package/src/theme/colors.ts +32 -0
  839. package/src/theme/font-scale.ts +2 -0
  840. package/src/theme/ui-tokens.ts +71 -0
  841. package/src/tickers/batched-lookups.ts +186 -0
  842. package/src/tickers/company-name-listing.ts +97 -0
  843. package/src/tickers/company-name.ts +13 -0
  844. package/src/tickers/instrument-coverage.ts +112 -0
  845. package/src/tickers/listing-fate.ts +282 -0
  846. package/src/tickers/listing-venues.ts +24 -5
  847. package/src/tickers/open-target.ts +13 -5
  848. package/src/tickers/search/index.ts +156 -37
  849. package/src/tickers/search/ranking.ts +68 -3
  850. package/src/tickers/search/types.ts +3 -0
  851. package/src/tickers/search/upsert.ts +22 -7
  852. package/src/tickers/terminal-codes.ts +79 -0
  853. package/src/tickers/ticker-changes.ts +100 -12
  854. package/src/tickers/us-listing.ts +2 -1
  855. package/src/time-series/bar-spacing.ts +19 -0
  856. package/src/time-series/chart-data.ts +116 -21
  857. package/src/time-series/field-catalog.ts +5 -2
  858. package/src/time-series/forward-valuation.ts +10 -7
  859. package/src/time-series/fundamentals.ts +103 -17
  860. package/src/time-series/hooks.ts +2 -0
  861. package/src/time-series/ice-credit.ts +17 -2
  862. package/src/time-series/live-bars.ts +24 -9
  863. package/src/time-series/live-quotes.ts +2 -3
  864. package/src/time-series/parsed-history-cache.ts +2 -0
  865. package/src/time-series/price-comparison.ts +6 -1
  866. package/src/time-series/price-units.ts +69 -0
  867. package/src/time-series/resolve.ts +114 -14
  868. package/src/time-series/session-bar.ts +138 -0
  869. package/src/time-series/spec.ts +14 -4
  870. package/src/time-series/studies.ts +214 -15
  871. package/src/time-series/transforms.ts +2 -0
  872. package/src/time-series/types.ts +33 -1
  873. package/src/time-series/use-chart-resolution.ts +2 -1
  874. package/src/time-series/valuation-price.ts +13 -0
  875. package/src/types/config.ts +17 -1
  876. package/src/types/data-provider.ts +20 -0
  877. package/src/types/financials.ts +2 -0
  878. package/src/types/headless.ts +169 -1
  879. package/src/types/instrument.ts +6 -0
  880. package/src/types/plugin.ts +39 -9
  881. package/src/types/price-history.ts +5 -0
  882. package/src/types/ticker-changes.ts +19 -0
  883. package/src/types/ticker.ts +10 -2
  884. package/src/ui/context-menu.tsx +2 -0
  885. package/src/ui/host.tsx +45 -4
  886. package/src/ui/measured-cells.ts +13 -7
  887. package/src/ui/qr.ts +7 -5
  888. package/src/updater/index.ts +8 -6
  889. package/src/utils/asset-category.ts +20 -0
  890. package/src/utils/calendar-date.ts +86 -27
  891. package/src/utils/currency-units.ts +17 -0
  892. package/src/utils/debug-log.ts +1 -1
  893. package/src/utils/decimal-comma.ts +83 -3
  894. package/src/utils/dividend-cash.ts +48 -0
  895. package/src/utils/dom-screenshot-rasters.ts +3 -1
  896. package/src/utils/dom-screenshot.ts +14 -10
  897. package/src/utils/exchange-rate-snapshot.ts +9 -4
  898. package/src/utils/external-url.ts +1 -0
  899. package/src/utils/fiscal-period.ts +47 -0
  900. package/src/utils/format.ts +5 -2
  901. package/src/utils/forward-dividend.ts +160 -11
  902. package/src/utils/fundamentals.ts +7 -2
  903. package/src/utils/futures-generic.ts +34 -8
  904. package/src/utils/http-proxy-response.ts +67 -9
  905. package/src/utils/local-utc-offset.ts +2 -0
  906. package/src/utils/log-failure.ts +31 -0
  907. package/src/utils/option-expiry.ts +12 -12
  908. package/src/utils/plugin-proxy-hosts.json +1 -5
  909. package/src/utils/price-history-integrity.ts +56 -0
  910. package/src/utils/price-history.ts +13 -1
  911. package/src/utils/sec-filings.ts +245 -0
  912. package/src/utils/selection-clipboard.ts +5 -2
  913. package/src/utils/throttled-fetch.ts +1 -0
  914. package/src/{plugins/builtin/dividend-yield/trailing-cash.ts → utils/trailing-dividend.ts} +55 -8
  915. package/src/utils/typo-distance.ts +22 -0
  916. package/src/utils/url.ts +1 -0
  917. package/src/utils/utc-time.ts +11 -0
  918. package/src/plugins/builtin/chat/share/targets.ts +0 -27
  919. package/src/plugins/builtin/shared/zip-text.ts +0 -46
  920. package/src/renderers/dom/host/top-surface.ts +0 -119
  921. package/src/shares/dialog.tsx +0 -221
  922. package/src/shares/live.ts +0 -19
@@ -32,14 +32,27 @@ export interface FuturesContractTermsPayload {
32
32
  settlement: { price: number; date: string } | null
33
33
  /**
34
34
  * For a continuous symbol (CL=F) or a front generic: the nearest contract
35
- * still trading when the symbol has rolled past it to the most active one,
36
- * with its last trade; null when it prices the nearest itself. Absent from
35
+ * still trading once the symbol has rolled past it on its roll date, with
36
+ * its last trade; null when it prices the nearest itself. Absent from
37
37
  * servers that do not send it.
38
38
  */
39
39
  nearest?: FuturesNearestContract | null
40
+ /**
41
+ * For a continuous symbol or a generic: how it rolls ("1 day before last
42
+ * trade") and the first session it is on the next contract; the date is
43
+ * null under the open interest switch. Absent from older servers.
44
+ */
45
+ roll?: { label: string; date: string | null } | null
46
+ /**
47
+ * The root's front contract (what its continuous symbol and first generic
48
+ * price) when the symbol prices another one (NGF27, NG2); null on the front.
49
+ */
50
+ front?: FuturesNearestContract | null
51
+ /** The contract that traded the most on the root's newest session with volumes: the day's volume alone. */
52
+ mostActive?: FuturesMostActiveContract | null
40
53
  }
41
54
 
42
- /** The nearest contract still trading, which a continuous symbol has rolled past (CLX26 under CL=F on Dec). */
55
+ /** A listed contract by its code, as the quote endpoints take it (CLX26.NYM), and its last trade. */
43
56
  interface FuturesNearestContract {
44
57
  contract: string
45
58
  contractSymbol: string
@@ -48,6 +61,16 @@ interface FuturesNearestContract {
48
61
  lastTrade: string | null
49
62
  }
50
63
 
64
+ /** The most active contract: its volume on that session (`date`). */
65
+ interface FuturesMostActiveContract {
66
+ contract: string
67
+ contractSymbol: string
68
+ /** YYYY-MM */
69
+ deliveryMonth: string
70
+ volume: number
71
+ date: string
72
+ }
73
+
51
74
  /** Gloom Cloud futures prices retain provider denomination and explicit quote units. */
52
75
  export interface FuturesContract {
53
76
  symbol: string
@@ -9,6 +9,8 @@
9
9
  * `geo_unavailable`. A layer that cannot serve still answers 200 with an
10
10
  * empty body and its `status` and `statusNote`.
11
11
  */
12
+ import { logFailure } from "../utils/log-failure";
13
+
12
14
  type Lon = number;
13
15
  type Lat = number;
14
16
 
@@ -79,6 +81,12 @@ export interface GeoLayerInfo {
79
81
  status: GeoLayerStatus;
80
82
  /** Short plain words, never a source name. */
81
83
  statusNote?: string;
84
+ /**
85
+ * Who published the data, as a reader cites it (`IMF PortWatch`), when the
86
+ * server names one: a public institution, never a vendor. Reports cite it
87
+ * as their source and publisher; absent, they cite Gloom Cloud.
88
+ */
89
+ publisher?: string;
82
90
  access: "free" | "pro";
83
91
  /** The entity table's columns; the first is the label. */
84
92
  columns: GeoColumn[];
@@ -162,6 +170,8 @@ export interface GeoSeriesPayload {
162
170
  /** [YYYY-MM-DD, value], oldest first. */
163
171
  points: [string, number][];
164
172
  asOf: string | null;
173
+ /** Its layer's `publisher`, when the server names one. */
174
+ publisher?: string;
165
175
  }
166
176
 
167
177
  /** West, south, east, north in degrees. */
@@ -329,7 +339,7 @@ export async function loadGeoCatalog(
329
339
  catalogInFlight = request<unknown>("layers")
330
340
  .then(normalizeCatalog)
331
341
  // A missing route or a refusal is an answer; a network blip is too, for a while.
332
- .catch(() => null)
342
+ .catch(logFailure("cloud-geo", "Geo catalog request failed", null))
333
343
  .then((payload) => {
334
344
  catalogEntry = { at: options.now ?? Date.now(), payload };
335
345
  return payload;
@@ -1,3 +1,4 @@
1
+ import { logFailure } from "../utils/log-failure";
1
2
  import {
2
3
  isMarketplaceLayoutId,
3
4
  parseMarketplaceLayoutEntry,
@@ -420,6 +421,19 @@ class GloomApiClient {
420
421
  return this.request<{ url: string }>("/stripe/portal", { method: "POST", body: JSON.stringify({}) });
421
422
  }
422
423
 
424
+ /**
425
+ * Ends the Pro trial and Pro now, unbilled. Call it only once the person
426
+ * confirmed a warning that says so. `endedNow` is false when the server
427
+ * scheduled the cancel at the period end instead: the subscription was no
428
+ * longer in its trial, or the server predates ending a trial early.
429
+ */
430
+ async endCloudTrial(): Promise<{ canceled: boolean; endedNow?: boolean }> {
431
+ return this.request<{ canceled: boolean; endedNow?: boolean }>("/stripe/subscription/cancel", {
432
+ method: "POST",
433
+ body: JSON.stringify({ endTrialNow: true }),
434
+ });
435
+ }
436
+
423
437
  /**
424
438
  * Asks which arm of an app experiment this account or web visitor is in, at the
425
439
  * moment it would show. The API counts the answer as the exposure.
@@ -636,8 +650,9 @@ class GloomApiClient {
636
650
  reportCommandSearch(report: CommandSearchReport): void {
637
651
  try {
638
652
  if (!this.isSignedIn()) return;
639
- void this.telemetry.reportCommandSearch(report).catch(() => {});
640
- } catch {
653
+ void this.telemetry.reportCommandSearch(report).catch(logFailure("cloud-telemetry", "Command search report failed"));
654
+ } catch (error) {
655
+ logFailure("cloud-telemetry", "Command search reporting failed")(error);
641
656
  /* A report must never get in the way of the command bar. */
642
657
  }
643
658
  }
@@ -645,6 +660,8 @@ class GloomApiClient {
645
660
  getChannels = this.chat.getChannels.bind(this.chat);
646
661
  getChatPresence = this.chat.getPresence.bind(this.chat);
647
662
  getChatState = this.chat.getState.bind(this.chat);
663
+ getChatMentionCandidates = this.chat.getMentionCandidates.bind(this.chat);
664
+ subscribeChatMentionCandidatesChanged = this.chat.subscribeMentionCandidatesChanged.bind(this.chat);
648
665
  updateChatChannelState = this.chat.updateChannelState.bind(this.chat);
649
666
  markChatNotificationsDelivered = this.chat.markNotificationsDelivered.bind(this.chat);
650
667
  getUnseenChatNotificationIds = this.chat.getUnseenNotificationIds.bind(this.chat);
@@ -756,9 +773,12 @@ class GloomApiClient {
756
773
  getCloudCorporateActions = this.data.getCloudCorporateActions.bind(this.data);
757
774
  getCloudTickerChanges = this.data.getCloudTickerChanges.bind(this.data);
758
775
  getCloudOrganizationTickers = this.data.getCloudOrganizationTickers.bind(this.data);
776
+ getCloudTickerChangesBatch = this.data.getCloudTickerChangesBatch.bind(this.data);
777
+ searchInstrumentsBatch = this.data.searchInstrumentsBatch.bind(this.data);
759
778
  getCloudHistory = this.data.getCloudHistory.bind(this.data);
760
779
  getCloudExchangeRate = this.data.getCloudExchangeRate.bind(this.data);
761
780
  getCloudEconomicCalendar = this.data.getCloudEconomicCalendar.bind(this.data);
781
+ getCloudEconomicCalendarFrom = this.data.getCloudEconomicCalendarFrom.bind(this.data);
762
782
  getCloudMacroReleaseDays = this.data.getCloudMacroReleaseDays.bind(this.data);
763
783
  getCloudEquityDiagnostic = this.data.getCloudEquityDiagnostic.bind(this.data);
764
784
  getCloudEarningsCalendar = this.data.getCloudEarningsCalendar.bind(this.data);
@@ -766,6 +786,8 @@ class GloomApiClient {
766
786
  getCloudFredSeries = this.data.getCloudFredSeries.bind(this.data);
767
787
  getCloudFredSeriesCatalog = this.data.getCloudFredSeriesCatalog.bind(this.data);
768
788
  getCloudCryptoMarkets = this.data.getCloudCryptoMarkets.bind(this.data);
789
+ getCloudStablecoinSupply = this.data.getCloudStablecoinSupply.bind(this.data);
790
+ getCloudStablecoinSupplyHistory = this.data.getCloudStablecoinSupplyHistory.bind(this.data);
769
791
  getCloudCentralBankRates = this.data.getCloudCentralBankRates.bind(this.data);
770
792
  getMobileAlertHistory = this.data.getMobileAlertHistory.bind(this.data);
771
793
  getScannerFlowHistory = this.data.getScannerFlowHistory.bind(this.data);
@@ -775,10 +797,12 @@ class GloomApiClient {
775
797
  getMemberFunds = this.data.getMemberFunds.bind(this.data);
776
798
  getFundMembers = this.data.getFundMembers.bind(this.data);
777
799
  getFundChanges = this.data.getFundChanges.bind(this.data);
800
+ getFundFacts = this.data.getFundFacts.bind(this.data);
778
801
  getCloudThemes = this.data.getCloudThemes.bind(this.data);
779
802
  getCloudThemeMembers = this.data.getCloudThemeMembers.bind(this.data);
780
803
  impliedVolatility = this.data.impliedVolatility.bind(this.data);
781
804
  optionsPositioning = this.data.optionsPositioning.bind(this.data);
805
+ getCloudBankFigures = this.data.getCloudBankFigures.bind(this.data);
782
806
  getCloudDebtMaturities = this.data.getCloudDebtMaturities.bind(this.data);
783
807
  getCloudRevenueBreakdown = this.data.getCloudRevenueBreakdown.bind(this.data);
784
808
  getCloudMnaDeals = this.data.getCloudMnaDeals.bind(this.data);
@@ -826,6 +850,8 @@ class GloomApiClient {
826
850
  getCloudAward = this.data.getCloudAward.bind(this.data);
827
851
  getCloudDoeBoard = this.data.getCloudDoeBoard.bind(this.data);
828
852
  getCloudDoePrices = this.data.getCloudDoePrices.bind(this.data);
853
+ getCloudJodiBoard = this.data.getCloudJodiBoard.bind(this.data);
854
+ getCloudPsdBoard = this.data.getCloudPsdBoard.bind(this.data);
829
855
  getCloudAttention = this.data.getCloudAttention.bind(this.data);
830
856
  getCloudPowerBoard = this.data.getCloudPowerBoard.bind(this.data);
831
857
  getCloudPowerHistory = this.data.getCloudPowerHistory.bind(this.data);
@@ -857,6 +883,7 @@ class GloomApiClient {
857
883
  getCloudJobsMovers = this.data.getCloudJobsMovers.bind(this.data);
858
884
  getCloudEarningsCalls = this.data.getCloudEarningsCalls.bind(this.data);
859
885
  getCloudEarningsTranscript = this.data.getCloudEarningsTranscript.bind(this.data);
886
+ getCloudEarningsCallAudio = this.data.getCloudEarningsCallAudio.bind(this.data);
860
887
  getProxyStatements = this.data.getProxyStatements.bind(this.data);
861
888
  getProxyStatement = this.data.getProxyStatement.bind(this.data);
862
889
  getFilingEvents = this.data.getFilingEvents.bind(this.data);
@@ -864,6 +891,7 @@ class GloomApiClient {
864
891
  getRiskReport = this.data.getRiskReport.bind(this.data);
865
892
  getCloudSecFilings = this.data.getCloudSecFilings.bind(this.data);
866
893
  getCloudSecBeneficialOwners = this.data.getCloudSecBeneficialOwners.bind(this.data);
894
+ getCloudSecInsiderSignals = this.data.getCloudSecInsiderSignals.bind(this.data);
867
895
  getCloudSecFilingDocuments = this.data.getCloudSecFilingDocuments.bind(this.data);
868
896
  getCloudSecFilingContent = this.data.getCloudSecFilingContent.bind(this.data);
869
897
  getCloudSec13F = this.data.getCloudSec13F.bind(this.data);
@@ -0,0 +1,159 @@
1
+ /**
2
+ * Companies ranked by recent open-market insider buying or selling, as
3
+ * `GET /cloud/sec/insider-signals` returns them. Buying counts Form 4
4
+ * purchases (code P), selling the sales (code S) an insider chose to make: a
5
+ * Rule 10b5-1 plan's, a sell-to-cover's, an option exercise's and an
6
+ * offering's are left out. Only officers, directors and 10% owners count.
7
+ * Dates are `YYYY-MM-DD`, values USD.
8
+ */
9
+
10
+ export type InsiderSignalRole =
11
+ | "CEO"
12
+ | "CFO"
13
+ | "COO"
14
+ | "President"
15
+ | "Chair"
16
+ | "Officer"
17
+ | "Director"
18
+ | "10% owner";
19
+
20
+ /** Purchases or sales. */
21
+ export type InsiderSignalSide = "buy" | "sell";
22
+ /** Whose trades a ranking reads: everyone, chief officers and other officers, directors, or 10% owners. */
23
+ export type InsiderSignalRoleGroup = "all" | "officers" | "directors" | "owners";
24
+ /** Market value: micro under $300M, small to $2B, mid to $10B, large above. */
25
+ export type InsiderSignalCap = "micro" | "small" | "mid" | "large";
26
+
27
+ /**
28
+ * One insider in a row: what they traded in the window. On the sell side
29
+ * `buys` and `lastBuy` are the days they sold and the last of them.
30
+ */
31
+ export interface InsiderSignalBuyer {
32
+ name: string;
33
+ role: InsiderSignalRole;
34
+ value: number;
35
+ /** Days the insider traded in the window. */
36
+ buys: number;
37
+ lastBuy: string;
38
+ /** Left out by servers that predate selling. */
39
+ shares?: number;
40
+ /** The holding's change in the window, percent: positive bought, negative sold; null without balances. */
41
+ stakeChangePct?: number | null;
42
+ /** Opened a position: held nothing before, or a holding worth under $10K or under 1% of what was bought. */
43
+ newPosition?: boolean;
44
+ /** Sold every share and unit the forms report. */
45
+ exited?: boolean;
46
+ /**
47
+ * The insider's trade days in the 90 days ending on their last, the days
48
+ * before the window included: their nth buy (sale), 1 for a lone day. Null
49
+ * when they traded both ways. Left out by servers that predate it.
50
+ */
51
+ repeatBuys?: number | null;
52
+ /**
53
+ * Their largest day in the window against their usual size, to a tenth and
54
+ * at most 100 ("100x+"); null without enough history, or when they traded
55
+ * both ways. Left out by servers that predate it.
56
+ */
57
+ usualRatio?: number | null;
58
+ /** Bought and sold in the window: the row counts the net, on the side it falls. */
59
+ twoWay?: boolean;
60
+ }
61
+
62
+ /** One fact behind a row, structured, strongest first. */
63
+ interface InsiderWhySignal {
64
+ kind: "cluster" | "repeat" | "usual" | "stake" | "new" | "exited" | "size" | "both";
65
+ /** cluster: insiders; repeat: the ordinal; usual: the multiple; stake: percent, negative sold; new, exited, both: 1; size: dollars. */
66
+ value: number;
67
+ /** A few characters: "3 insiders", "4th buy", "5x usual", "+56%", "6x stake", "NEW", "both ways". */
68
+ text: string;
69
+ /** The insider it is about; null for the company's (a cluster). */
70
+ insider: { name: string; role: InsiderSignalRole } | null;
71
+ }
72
+
73
+ export interface InsiderSignalRow {
74
+ ticker: string;
75
+ issuerCik: string;
76
+ company: string;
77
+ /** 0 to 100. */
78
+ score: number;
79
+ /** Why the company ranks, strongest first, in plain words. */
80
+ reasons: string[];
81
+ /** Distinct insiders who traded in the window. */
82
+ insiders: number;
83
+ /** Insider trade days in the window. */
84
+ buys: number;
85
+ value: number;
86
+ shares: number;
87
+ firstBuy: string;
88
+ lastBuy: string;
89
+ lastFiled: string;
90
+ signals: {
91
+ clusterInsiders: number;
92
+ repeatBuys: number;
93
+ usualRatio: number | null;
94
+ stakeIncreasePct: number | null;
95
+ newPosition: boolean;
96
+ /** Left out by servers that predate selling. */
97
+ stakeChangePct?: number | null;
98
+ exited?: boolean;
99
+ };
100
+ /** The reasons' facts, structured; left out by servers that predate them. */
101
+ whySignals?: InsiderWhySignal[];
102
+ /** The insiders who traded, largest first, up to ten. */
103
+ buyers: InsiderSignalBuyer[];
104
+ /** Stored market value, USD; null when the server has none for it. */
105
+ marketCap?: number | null;
106
+ }
107
+
108
+ interface InsiderSignalsFilters {
109
+ role: InsiderSignalRoleGroup;
110
+ minValue: number;
111
+ cluster: boolean;
112
+ position: "new" | "exited" | null;
113
+ cap: InsiderSignalCap | null;
114
+ }
115
+
116
+ export interface InsiderSignalsPayload {
117
+ /**
118
+ * The company asked for (`ticker`): `rows` is its row alone, with every
119
+ * insider, whatever its size. Absent for the ranking, and from a server
120
+ * that predates the question, which answers the ranking instead.
121
+ */
122
+ ticker?: string;
123
+ /** Left out by servers that predate selling: buying. */
124
+ side?: InsiderSignalSide;
125
+ /** Days of trading each row covers, ending `through`. */
126
+ window: number;
127
+ filters?: InsiderSignalsFilters;
128
+ /** Whether rows carry market values, so the cap filter can work. */
129
+ marketCaps?: "stored" | "unavailable";
130
+ through: string;
131
+ /** The newest filing day read. */
132
+ asOf: string | null;
133
+ /**
134
+ * Days whose filings have all been read. `missingDays`: weekdays since
135
+ * `from` the server no longer reads on its own and has not read whole, a gap
136
+ * an outage left (left out by servers that predate it).
137
+ */
138
+ coverage: { from: string | null; through: string | null; missingDays?: string[] };
139
+ rows: InsiderSignalRow[];
140
+ }
141
+
142
+ export interface CloudInsiderSignalsParams {
143
+ /** Buying unless told. */
144
+ side?: InsiderSignalSide;
145
+ /** Days, 1 to 90; the server reads 30 when left out. */
146
+ window?: number;
147
+ /** Rows, 1 to 200; the server reads 50 when left out. */
148
+ limit?: number;
149
+ role?: InsiderSignalRoleGroup;
150
+ /** USD the insiders traded in the window, at least. */
151
+ minValue?: number;
152
+ /** Only companies where two insiders or more traded within a span. */
153
+ cluster?: boolean;
154
+ /** "new" on the buy side, "exited" on the sell side. */
155
+ position?: "new" | "exited";
156
+ cap?: InsiderSignalCap;
157
+ /** One company instead of the ranking: its row, with every insider. */
158
+ ticker?: string;
159
+ }
@@ -19,7 +19,7 @@ export interface ScreenerQuote {
19
19
  lastUpdated?: number;
20
20
  /** Session-fixed, so the price column reads its decimals from it rather than from each tick. */
21
21
  previousClose?: number;
22
- /** The quote's sessions beside the live print the list ranks by, when the server sends them. */
22
+ /** The quote's sessions beside the live print the server ranked the row by, when the server sends them. */
23
23
  sessions?: CloudMoverSessionFields;
24
24
  }
25
25
 
@@ -134,6 +134,7 @@ export function normalizeChatMessage(message: ChatMessage): ChatMessage {
134
134
  if (paneLink) normalized.paneLink = paneLink;
135
135
  else delete normalized.paneLink;
136
136
  }
137
+ if ((message.announcement as unknown) !== true) delete normalized.announcement;
137
138
  return normalized;
138
139
  }
139
140
 
@@ -220,6 +221,7 @@ export function normalizeChatChannel(
220
221
  ...channel,
221
222
  kind: channel.kind ?? fallbackKind,
222
223
  created_at: normalizeTimestamp(channel.created_at),
224
+ ...(typeof channel.lastMessageAt === "string" ? { lastMessageAt: normalizeTimestamp(channel.lastMessageAt) } : {}),
223
225
  ...(channel.dmUser ? { dmUser: normalizeChatUser(channel.dmUser) } : {}),
224
226
  ...(Array.isArray(channel.members) ? { members: channel.members.map(normalizeChatUser) } : {}),
225
227
  };
@@ -7,6 +7,7 @@ import { isUsListingExchange, normalizeSymbol, parsePublicTickerKey, publicTicke
7
7
  import { nonUsSecListingVenue } from "../utils/sec";
8
8
  import type { HistoryRetention } from "../sources/history-retention";
9
9
  import type { CloudBeneficialOwnersParams } from "./beneficial-owners";
10
+ import type { CloudInsiderSignalsParams } from "./insider-signals";
10
11
  import type { RevenueBreakdownView } from "./revenue-breakdown";
11
12
 
12
13
  export type CloudHistoryParams = {
@@ -245,6 +246,8 @@ export type CloudSecFilingsParams = {
245
246
  name?: string;
246
247
  limit?: number;
247
248
  offset?: number;
249
+ /** Only these forms, each with its amendment (`8-K` is also `8-K/A`). A server that predates the filter sends every form. */
250
+ forms?: readonly string[];
248
251
  };
249
252
 
250
253
  export type CloudSecFilingParams = {
@@ -360,6 +363,10 @@ export function cloudEarningsTranscriptPath(id: string): string {
360
363
  return `/cloud/transcripts/${encodeURIComponent(id)}`;
361
364
  }
362
365
 
366
+ export function cloudEarningsCallAudioPath(id: string): string {
367
+ return `${cloudEarningsTranscriptPath(id)}/audio`;
368
+ }
369
+
363
370
  /**
364
371
  * An issuer read's path: a US listing or a bare symbol keeps its US ticker
365
372
  * and sends nothing else; a listing abroad sends its bare symbol with its
@@ -428,10 +435,16 @@ export function cloudSecFilingsPath(params: CloudSecFilingsParams): string {
428
435
  });
429
436
  if (params.limit != null) search.set("limit", String(params.limit));
430
437
  if (params.offset != null) search.set("offset", String(params.offset));
438
+ if (params.forms?.length) search.set("form", params.forms.join(","));
431
439
  setListingAbroad(search, abroad);
432
440
  return appendQuery("/cloud/sec/filings", search);
433
441
  }
434
442
 
443
+ /** A US-listed company's bank figures: SEC deposits and its lead bank's FDIC call report. */
444
+ export function cloudBankFiguresPath(symbol: string): string {
445
+ return appendQuery("/cloud/bank-figures", new URLSearchParams({ symbol }));
446
+ }
447
+
435
448
  /** Schedule 13D and 13G reports about the issuer behind `ticker`. */
436
449
  export function cloudSecBeneficialOwnersPath(params: CloudBeneficialOwnersParams): string {
437
450
  const abroad = listingAbroad(params.ticker, params.exchange, params.name);
@@ -444,6 +457,21 @@ export function cloudSecBeneficialOwnersPath(params: CloudBeneficialOwnersParams
444
457
  return appendQuery("/cloud/sec/beneficial-owners", search);
445
458
  }
446
459
 
460
+ /** Companies ranked by recent open-market insider buying or selling. Defaults are left out of the query. */
461
+ export function cloudSecInsiderSignalsPath(params: CloudInsiderSignalsParams = {}): string {
462
+ const search = new URLSearchParams();
463
+ if (params.side === "sell") search.set("side", "sell");
464
+ if (params.window != null) search.set("window", String(params.window));
465
+ if (params.limit != null) search.set("limit", String(params.limit));
466
+ if (params.role && params.role !== "all") search.set("role", params.role);
467
+ if (params.minValue) search.set("minValue", String(params.minValue));
468
+ if (params.cluster) search.set("cluster", "true");
469
+ if (params.position) search.set("position", params.position);
470
+ if (params.cap) search.set("cap", params.cap);
471
+ if (params.ticker) search.set("ticker", params.ticker);
472
+ return appendQuery("/cloud/sec/insider-signals", search);
473
+ }
474
+
447
475
  export function cloudSecFilingDocumentsPath(
448
476
  params: CloudSecFilingParams,
449
477
  ): string {
@@ -1,3 +1,4 @@
1
+ import { logFailure } from "../utils/log-failure";
1
2
  import { httpFetch, isHttpFetchStreaming } from "../utils/http-transport";
2
3
  import { withDeadline } from "../utils/async-deadline";
3
4
  import {
@@ -148,7 +149,7 @@ export async function putWithRevision<T, Current extends { revision: number }>(
148
149
  });
149
150
  } catch (error) {
150
151
  if (!(error instanceof ApiRequestError) || error.status !== 412) throw error;
151
- const current = await revision.loadCurrent().catch(() => null);
152
+ const current = await revision.loadCurrent().catch(logFailure("cloud-request", "Current revision request failed", null));
152
153
  throw new revision.conflict(error.message, current, current?.revision ?? (revision.expected ?? 0) + 1);
153
154
  }
154
155
  }
@@ -269,7 +270,7 @@ export class CloudApiRequestTransport {
269
270
  });
270
271
  throwIfRequestAborted(options.signal);
271
272
  if (!response.ok) {
272
- const text = await response.text().catch(() => "");
273
+ const text = await response.text().catch(logFailure("cloud-request", "Error response body read failed", ""));
273
274
  throw new ApiRequestError(
274
275
  parseApiErrorMessage(text),
275
276
  response.status,
@@ -411,12 +412,19 @@ export class CloudApiRequestTransport {
411
412
  // layers, which a server without them answers with 404, or a ticker
412
413
  // change lookup: a note beside a quote, never one of the refused market
413
414
  // requests a lookup of many symbols waits out and retries. Nor the
414
- // tickers beside a list of organization names, which say so in place.
415
+ // tickers beside a list of organization names, which say so in place,
416
+ // or a 13F filer's EDGAR filing list, whose report says it went unchecked.
417
+ // Nor the batched searches and ticker changes a list of symbols starts
418
+ // with: a service without them answers 404, and whatever they leave
419
+ // unanswered is looked up one symbol at a time, which is tracked.
415
420
  if (
416
421
  path.startsWith("/telemetry/")
417
422
  || path === "/assist/searches"
418
423
  || path === "/cloud/geo/layers"
424
+ || path.startsWith("/cloud/sec/13f/filer?")
419
425
  || path.startsWith("/market/ticker-changes?")
426
+ || path === "/market/ticker-changes/batch"
427
+ || path === "/market/search/batch"
420
428
  || path === "/market/organization-tickers"
421
429
  ) return request();
422
430
  return this.connectionHealth.track(
@@ -1,3 +1,4 @@
1
+ import { logFailure } from "../utils/log-failure";
1
2
  import { apiClient } from "./index";
2
3
  import { getCurrentPluginTarget } from "../plugins/current-target";
3
4
  import type { DesktopDeepLinkBridge } from "../types/desktop-deeplink";
@@ -99,6 +100,7 @@ function cleanUrlValue(value: unknown): string | undefined {
99
100
  new URL(cleaned);
100
101
  return cleaned;
101
102
  } catch {
103
+ // Intentional ignore: Malformed attribution URLs are excluded from the payload.
102
104
  return undefined;
103
105
  }
104
106
  }
@@ -122,7 +124,7 @@ export function readStoredAttribution(stored: string | null, now = Date.now()):
122
124
  const parsed: unknown = JSON.parse(stored ?? "{}");
123
125
  if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) saved = parsed as Record<string, unknown>;
124
126
  } catch {
125
- /* Corrupt storage is the same as no storage. */
127
+ // Intentional ignore: Corrupt optional attribution is treated as absent.
126
128
  }
127
129
 
128
130
  const next: Record<string, string> = {};
@@ -170,6 +172,7 @@ export function carriesHandoff(href: string): boolean {
170
172
  FIRST_TOUCH_KEYS.some((key) => params.has(key))
171
173
  );
172
174
  } catch {
175
+ // Intentional ignore: Malformed links carry no usable attribution handoff.
173
176
  return false;
174
177
  }
175
178
  }
@@ -258,7 +261,7 @@ export function initializeBrowserResearchActivity(): void {
258
261
  stripHandoffParams(url);
259
262
  history.replaceState(history.state, "", url.href);
260
263
  } catch {
261
- /* Private browsing must still work. */
264
+ // Intentional ignore: Private browsing may deny optional attribution storage.
262
265
  }
263
266
  }
264
267
 
@@ -275,7 +278,7 @@ export function initializeDesktopResearchActivity(storage: StorageLike = localSt
275
278
  anonymousId = stored && ANONYMOUS_ID.test(stored) ? stored : undefined;
276
279
  attribution = readStoredAttribution(storage.getItem(ATTRIBUTION_STORAGE_KEY));
277
280
  } catch {
278
- /* A read-only profile still runs the app. */
281
+ // Intentional ignore: A read-only profile may deny optional attribution storage.
279
282
  }
280
283
  }
281
284
 
@@ -297,6 +300,7 @@ export function adoptDesktopHandoff(href: string, storage: StorageLike = localSt
297
300
  storage.setItem(ATTRIBUTION_STORAGE_KEY, JSON.stringify(attribution));
298
301
  return true;
299
302
  } catch {
303
+ // Intentional ignore: Optional attribution storage may be unavailable; the deep link still opens.
300
304
  return false;
301
305
  }
302
306
  }
@@ -406,9 +410,10 @@ export function recordResearchActivity(
406
410
  if (!wallEvent) return;
407
411
  const views = wallSessionViews();
408
412
  views.add(key);
409
- try { sessionStorage.setItem(WALL_VIEWS_SESSION_KEY, JSON.stringify([...views])); } catch { /* Native sessions use the in-memory set. */ }
413
+ try { sessionStorage.setItem(WALL_VIEWS_SESSION_KEY, JSON.stringify([...views])); } catch { /* Intentional ignore: Native sessions retain wall views in the in-memory set. */ }
410
414
  })
411
- .catch(() => {
415
+ .catch((error) => {
416
+ logFailure("cloud-telemetry", "Research activity request failed")(error);
412
417
  sent.delete(key);
413
418
  });
414
419
  }
@@ -432,7 +437,8 @@ export function recordResearchTabView(tabId: string, fromExternalPlugin: boolean
432
437
  export function identifyResearchUser(): void {
433
438
  try {
434
439
  recordResearchActivity("workspace_opened");
435
- } catch {
440
+ } catch (error) {
441
+ logFailure("cloud-telemetry", "Research identity reporting failed")(error);
436
442
  /* Analytics never blocks sign-in. */
437
443
  }
438
444
  }
@@ -444,6 +450,7 @@ function webExperimentAttribution(): { experiments?: string } {
444
450
  const experiments = storedExperimentAssignments(localStorage);
445
451
  return experiments ? { experiments } : {};
446
452
  } catch {
453
+ // Intentional ignore: Unavailable optional storage contributes no experiment attribution.
447
454
  return {};
448
455
  }
449
456
  }
@@ -499,7 +506,7 @@ function wallExperimentContext(): WallExperimentContext {
499
506
  try {
500
507
  if (surface === "web") local = localStorage;
501
508
  if (surface === "web" || surface === "desktop") session = sessionStorage;
502
- } catch { /* Native and private sessions keep their answer in memory. */ }
509
+ } catch { /* Intentional ignore: Native and private sessions keep experiment answers in memory. */ }
503
510
  return {
504
511
  surface,
505
512
  accountId: user?.id,
@@ -516,7 +523,7 @@ function wallSessionViews(): Set<string> {
516
523
  try {
517
524
  const saved: unknown = JSON.parse(sessionStorage.getItem(WALL_VIEWS_SESSION_KEY) ?? "[]");
518
525
  if (Array.isArray(saved)) return new Set(saved.filter((value): value is string => typeof value === "string"));
519
- } catch { /* Native sessions use the in-memory set. */ }
526
+ } catch { /* Intentional ignore: Native sessions retain wall views in the in-memory set. */ }
520
527
  return new Set();
521
528
  }
522
529
 
@@ -1,3 +1,4 @@
1
+ import { logFailure } from "../utils/log-failure";
1
2
  import type { TapeFeedEvent } from "./tape";
2
3
  import type {
3
4
  AuthUser,
@@ -109,6 +110,7 @@ export class CloudApiSocket {
109
110
  private reconnectDelayMs = 1000;
110
111
 
111
112
  private readonly channelListeners = new Map<string, Set<ChannelListener>>();
113
+ private readonly chatMentionCandidatesListeners = new Set<() => void>();
112
114
  private readonly chatNotificationListeners =
113
115
  new Set<ChatNotificationListener>();
114
116
  private readonly chatChannelStateListeners =
@@ -187,7 +189,7 @@ export class CloudApiSocket {
187
189
  try {
188
190
  ws?.close();
189
191
  } catch {
190
- // ignore closed sockets
192
+ // Intentional ignore: Closing an already closed socket needs no further cleanup.
191
193
  }
192
194
  }
193
195
 
@@ -254,6 +256,11 @@ export class CloudApiSocket {
254
256
  };
255
257
  }
256
258
 
259
+ subscribeChatMentionCandidatesChanged(listener: () => void): () => void {
260
+ this.chatMentionCandidatesListeners.add(listener);
261
+ return () => { this.chatMentionCandidatesListeners.delete(listener); };
262
+ }
263
+
257
264
  /**
258
265
  * The reader's read state or mute changed on another device or window. Like
259
266
  * notifications, it never opens the socket by itself.
@@ -306,7 +313,8 @@ export class CloudApiSocket {
306
313
  try {
307
314
  this.ws.send(JSON.stringify(payload));
308
315
  return true;
309
- } catch {
316
+ } catch (error) {
317
+ logFailure("cloud-socket", "WebSocket frame send failed")(error);
310
318
  return false;
311
319
  }
312
320
  }
@@ -551,7 +559,8 @@ export class CloudApiSocket {
551
559
  let parsed: any;
552
560
  try {
553
561
  parsed = JSON.parse(raw);
554
- } catch {
562
+ } catch (error) {
563
+ logFailure("cloud-socket", "WebSocket message decoding failed")(error);
555
564
  return;
556
565
  }
557
566
 
@@ -631,6 +640,10 @@ export class CloudApiSocket {
631
640
  return;
632
641
  }
633
642
 
643
+ if (parsed?.type === "chat.mentions_changed") {
644
+ for (const listener of this.chatMentionCandidatesListeners) listener();
645
+ return;
646
+ }
634
647
  if (parsed?.type === "chat.channel_state") {
635
648
  const state = normalizeChatChannelStateFrame(parsed.data);
636
649
  if (state) {