gloomberb 0.18.4 → 0.19.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 (600) hide show
  1. package/README.md +1 -1
  2. package/README.zh-CN.md +1 -1
  3. package/package.json +1 -1
  4. package/patches/electrobun@1.18.1.patch +169 -5
  5. package/src/account/auth-model.ts +7 -3
  6. package/src/api-client/auth.ts +9 -4
  7. package/src/api-client/catalysts.ts +2 -1
  8. package/src/api-client/cot.ts +6 -2
  9. package/src/api-client/credit-documents.ts +6 -0
  10. package/src/api-client/data.ts +31 -6
  11. package/src/api-client/equity-screener.ts +24 -0
  12. package/src/api-client/fund-facts.ts +45 -4
  13. package/src/api-client/index.ts +171 -11
  14. package/src/api-client/live-scan.ts +91 -0
  15. package/src/api-client/market-discovery.ts +10 -0
  16. package/src/api-client/market-movers.ts +7 -0
  17. package/src/api-client/members.ts +13 -1
  18. package/src/api-client/perps.ts +43 -0
  19. package/src/api-client/request.ts +222 -41
  20. package/src/api-client/research-activity.ts +6 -12
  21. package/src/api-client/types.ts +74 -0
  22. package/src/app/keybindings/index.ts +3 -0
  23. package/src/app/keybindings/labels.ts +18 -1
  24. package/src/app/keybindings/resolve.ts +14 -0
  25. package/src/app/pane-runtime/plugin-bindings.ts +9 -5
  26. package/src/app/runtime/broker-import.ts +42 -27
  27. package/src/app/runtime/plugin-bindings.ts +73 -56
  28. package/src/architecture/core-builtin-allowlist.json +1 -1
  29. package/src/architecture/pane-tabs-allowlist.json +3 -0
  30. package/src/architecture/ttl-caches-allowlist.json +19 -0
  31. package/src/brokers/sync-broker-instance.ts +2 -8
  32. package/src/capabilities/chart-series.ts +1 -1
  33. package/src/cli/commands/crypto-hints.ts +40 -24
  34. package/src/cli/commands/fred-series.ts +5 -0
  35. package/src/cli/commands/keybindings.ts +23 -0
  36. package/src/cli/commands/market.ts +138 -46
  37. package/src/cli/commands/options-chain.ts +107 -10
  38. package/src/cli/commands/options-leaps.ts +9 -3
  39. package/src/cli/commands/overview.ts +176 -39
  40. package/src/cli/commands/search.ts +39 -3
  41. package/src/cli/commands/themes.ts +11 -2
  42. package/src/cli/commands/ticker.ts +57 -35
  43. package/src/cli/company-name-hint.ts +41 -0
  44. package/src/cli/earnings-calendar.ts +1 -1
  45. package/src/cli/errors.ts +10 -2
  46. package/src/cli/export-source.ts +29 -1
  47. package/src/cli/glossary.ts +73 -1
  48. package/src/cli/history-rows.ts +87 -16
  49. package/src/cli/index.ts +2 -0
  50. package/src/cli/known-gaps.ts +5 -2
  51. package/src/cli/listing-arg.ts +195 -56
  52. package/src/cli/output-file.ts +68 -0
  53. package/src/cli/pane-functions/capabilities.ts +3 -0
  54. package/src/cli/pane-functions/catalog.ts +80 -7
  55. package/src/cli/pane-functions/dom.ts +13 -3
  56. package/src/cli/pane-functions/freshness.ts +111 -16
  57. package/src/cli/pane-functions/function-help.ts +23 -13
  58. package/src/cli/pane-functions/headless.ts +56 -12
  59. package/src/cli/pane-functions/index.ts +58 -16
  60. package/src/cli/pane-functions/market-session.ts +81 -9
  61. package/src/cli/pane-functions/options.ts +19 -1
  62. package/src/cli/pane-functions/report.ts +5 -1
  63. package/src/cli/pane-functions/resolver.ts +35 -8
  64. package/src/cli/pane-functions/screenshot-assessment.ts +6 -4
  65. package/src/cli/pane-functions/screenshot-types.ts +5 -0
  66. package/src/cli/quote-answer.ts +30 -13
  67. package/src/cli/report-tables.ts +18 -7
  68. package/src/cli/restore-plugins.ts +13 -1
  69. package/src/cli/result.ts +57 -5
  70. package/src/cli/ticker-resolution.ts +3 -2
  71. package/src/components/chart/composite/composite-chart.tsx +26 -4
  72. package/src/components/chart/composite/format.ts +27 -0
  73. package/src/components/chart/composite/interactions.ts +6 -0
  74. package/src/components/chart/composite/legend.tsx +45 -7
  75. package/src/components/chart/composite/levels.ts +2 -0
  76. package/src/components/chart/composite/panel-gestures.ts +33 -0
  77. package/src/components/chart/composite/panel-series.ts +1 -0
  78. package/src/components/chart/composite/panel-surface.tsx +61 -5
  79. package/src/components/chart/composite/range-statistics.ts +62 -0
  80. package/src/components/chart/composite/rasterizer.ts +24 -13
  81. package/src/components/chart/composite/scene.ts +46 -7
  82. package/src/components/chart/composite/series-axis-tags.tsx +16 -9
  83. package/src/components/chart/composite/series-cues.ts +14 -0
  84. package/src/components/chart/composite/text-renderer.ts +9 -2
  85. package/src/components/chart/composite/tool-catalog.ts +36 -0
  86. package/src/components/chart/composite/tools.ts +203 -44
  87. package/src/components/chart/composite/types.ts +4 -0
  88. package/src/components/chart/composite/use-composite-chart-keyboard.ts +11 -4
  89. package/src/components/command-bar/assist/inventory.ts +2 -1
  90. package/src/components/command-bar/commands/direct/index.ts +28 -13
  91. package/src/components/command-bar/pane-templates/items.ts +3 -2
  92. package/src/components/command-bar/panel/prompt-binding.ts +0 -8
  93. package/src/components/command-bar/workflow/alert.ts +1 -1
  94. package/src/components/command-bar/workflow/collection-actions.ts +3 -3
  95. package/src/components/layout/header.tsx +26 -40
  96. package/src/components/layout/pane/footer/index.tsx +1 -0
  97. package/src/components/layout/pane/footer/model.ts +27 -0
  98. package/src/components/onboarding/onboarding-frame.tsx +1 -1
  99. package/src/components/onboarding/onboarding-wizard.tsx +4 -1
  100. package/src/components/onboarding/portfolio-step/positions-panel.tsx +14 -9
  101. package/src/components/onboarding/wizard-broker-sync.ts +0 -1
  102. package/src/components/onboarding/wizard-positions.ts +3 -3
  103. package/src/components/ticker/list-table-view.tsx +4 -1
  104. package/src/components/ui/choice-dialog.tsx +23 -18
  105. package/src/components/ui/choice-groups.ts +18 -0
  106. package/src/components/ui/data-table/opentui/index.tsx +9 -7
  107. package/src/components/ui/data-table/opentui/model.ts +26 -1
  108. package/src/components/ui/data-table/types.ts +2 -0
  109. package/src/components/ui/display.tsx +5 -1
  110. package/src/components/ui/list-view.tsx +8 -4
  111. package/src/components/ui/query-bar-keys.tsx +2 -0
  112. package/src/components/ui/query-bar.tsx +1 -0
  113. package/src/components/ui/select-button.tsx +5 -1
  114. package/src/components/ui/select-field.tsx +1 -0
  115. package/src/components/ui/table-layout.ts +8 -5
  116. package/src/core/app-runtime.ts +2 -0
  117. package/src/core/app-services.ts +2 -2
  118. package/src/core/state/app/layout.ts +2 -0
  119. package/src/core/state/app/state.ts +9 -0
  120. package/src/core/state/app/types.ts +3 -0
  121. package/src/data/config/chart-settings.ts +1 -1
  122. package/src/data/json-ticker-repository.ts +17 -8
  123. package/src/data/saved-copies.ts +55 -16
  124. package/src/data/ticker-repository.ts +16 -9
  125. package/src/data/ticker-writes.ts +81 -0
  126. package/src/data/ttl-cache.ts +165 -0
  127. package/src/docs/snapshot.json +427 -216
  128. package/src/i18n/es.ts +19 -3
  129. package/src/i18n/ja.ts +19 -3
  130. package/src/i18n/ko.ts +19 -3
  131. package/src/i18n/zh-cn.ts +19 -3
  132. package/src/i18n/zh-tw.ts +19 -3
  133. package/src/market-data/coordinator/financials.ts +10 -2
  134. package/src/market-data/coordinator/index.ts +3 -1
  135. package/src/market-data/coordinator/quotes.ts +4 -2
  136. package/src/market-data/depositary-pair.ts +2 -2
  137. package/src/market-data/fund-facts.ts +50 -0
  138. package/src/market-data/market/change-basis.ts +48 -7
  139. package/src/market-data/market/dated-previous-close.ts +203 -0
  140. package/src/market-data/market/format.ts +25 -0
  141. package/src/market-data/market/freshness.ts +2 -1
  142. package/src/market-data/market/futures-week.ts +68 -0
  143. package/src/market-data/market/status.ts +16 -4
  144. package/src/market-data/options-alternatives.ts +141 -4
  145. package/src/market-data/quotes/contributions.ts +20 -2
  146. package/src/market-data/quotes/resolution.ts +3 -0
  147. package/src/market-data/selectors.ts +3 -0
  148. package/src/news/aggregator.ts +113 -9
  149. package/src/news/cloud-session.ts +21 -0
  150. package/src/news/hooks.ts +1 -0
  151. package/src/news/news-model.ts +1 -0
  152. package/src/news/types.ts +11 -0
  153. package/src/notifications/notification-log.ts +6 -4
  154. package/src/plugins/builtin/alerts/alert-engine.ts +25 -2
  155. package/src/plugins/builtin/alerts/alert-log.ts +33 -0
  156. package/src/plugins/builtin/alerts/calendar-events.ts +57 -6
  157. package/src/plugins/builtin/alerts/cli-forms.ts +216 -0
  158. package/src/plugins/builtin/alerts/cli.ts +380 -82
  159. package/src/plugins/builtin/alerts/command.ts +31 -0
  160. package/src/plugins/builtin/alerts/constants.ts +1 -1
  161. package/src/plugins/builtin/alerts/events-pane.tsx +19 -4
  162. package/src/plugins/builtin/alerts/fired-log.ts +113 -8
  163. package/src/plugins/builtin/alerts/format.ts +80 -4
  164. package/src/plugins/builtin/alerts/headless.ts +30 -7
  165. package/src/plugins/builtin/alerts/history-rows.ts +7 -3
  166. package/src/plugins/builtin/alerts/history.ts +2 -0
  167. package/src/plugins/builtin/alerts/index.tsx +135 -22
  168. package/src/plugins/builtin/alerts/live.ts +3 -3
  169. package/src/plugins/builtin/alerts/metric-command.ts +134 -0
  170. package/src/plugins/builtin/alerts/metric-data.ts +111 -0
  171. package/src/plugins/builtin/alerts/metric-model.ts +324 -0
  172. package/src/plugins/builtin/alerts/metric-parity-fixture.json +725 -0
  173. package/src/plugins/builtin/alerts/pane.tsx +90 -39
  174. package/src/plugins/builtin/alerts/quotes.ts +6 -0
  175. package/src/plugins/builtin/alerts/storage.ts +37 -10
  176. package/src/plugins/builtin/alerts/types.ts +7 -0
  177. package/src/plugins/builtin/analytics/index.tsx +2 -1
  178. package/src/plugins/builtin/analytics/risk-client.ts +16 -5
  179. package/src/plugins/builtin/analytics/risk-fx.ts +70 -15
  180. package/src/plugins/builtin/analytics/risk-headless.ts +27 -0
  181. package/src/plugins/builtin/analytics/risk-model.ts +55 -9
  182. package/src/plugins/builtin/analytics/risk-pane.tsx +8 -2
  183. package/src/plugins/builtin/attention/index.tsx +2 -1
  184. package/src/plugins/builtin/attention/listing.ts +14 -0
  185. package/src/plugins/builtin/backtest/headless.ts +10 -5
  186. package/src/plugins/builtin/backtest/pane.tsx +9 -4
  187. package/src/plugins/builtin/backtest/presets.ts +29 -3
  188. package/src/plugins/builtin/broker-manager/index.tsx +10 -5
  189. package/src/plugins/builtin/broker-manager/model.ts +6 -1
  190. package/src/plugins/builtin/broker-trading/controller.ts +22 -12
  191. package/src/plugins/builtin/broker-trading/index.tsx +13 -1
  192. package/src/plugins/builtin/broker-trading/order-feed.ts +9 -4
  193. package/src/plugins/builtin/broker-trading/pane.tsx +1 -1
  194. package/src/plugins/builtin/buildout/cells.tsx +12 -4
  195. package/src/plugins/builtin/buildout/format.ts +38 -0
  196. package/src/plugins/builtin/buildout/model/normalizers.ts +36 -1
  197. package/src/plugins/builtin/buildout/pane/index.tsx +4 -1
  198. package/src/plugins/builtin/buildout/table-model.ts +23 -2
  199. package/src/plugins/builtin/builtin-plugin-meta.ts +7 -3
  200. package/src/plugins/builtin/catalysts/model.ts +2 -1
  201. package/src/plugins/builtin/changelog/index.tsx +9 -6
  202. package/src/plugins/builtin/chart-composer/catalog-inventory.ts +6 -1
  203. package/src/plugins/builtin/chart-composer/chart-spec-edit.ts +1 -1
  204. package/src/plugins/builtin/chart-composer/cli-options.ts +9 -5
  205. package/src/plugins/builtin/chart-composer/data-catalog-pane.tsx +12 -2
  206. package/src/plugins/builtin/chart-composer/editor/controller.ts +4 -2
  207. package/src/plugins/builtin/chart-composer/editor/model.ts +2 -0
  208. package/src/plugins/builtin/chart-composer/editor.tsx +7 -5
  209. package/src/plugins/builtin/chart-composer/formula.ts +71 -18
  210. package/src/plugins/builtin/chart-composer/headless-schema.ts +21 -4
  211. package/src/plugins/builtin/chart-composer/headless.ts +19 -3
  212. package/src/plugins/builtin/chart-composer/index.tsx +1 -1
  213. package/src/plugins/builtin/chart-composer/pane.tsx +53 -9
  214. package/src/plugins/builtin/chart-composer/presets.ts +50 -15
  215. package/src/plugins/builtin/chart-composer/quick-add.tsx +40 -25
  216. package/src/plugins/builtin/chart-composer/session-history.ts +18 -9
  217. package/src/plugins/builtin/chart-composer/settings.ts +27 -0
  218. package/src/plugins/builtin/chart-composer/use-series-catalog.ts +40 -26
  219. package/src/plugins/builtin/chat/content/command-suggestions.ts +93 -0
  220. package/src/plugins/builtin/chat/content/composer.tsx +13 -6
  221. package/src/plugins/builtin/chat/content/footer.tsx +6 -3
  222. package/src/plugins/builtin/chat/content/index.tsx +50 -21
  223. package/src/plugins/builtin/chat/content/open-targets.ts +14 -3
  224. package/src/plugins/builtin/chat/controller/session-runtime.ts +4 -2
  225. package/src/plugins/builtin/chat/index.tsx +23 -0
  226. package/src/plugins/builtin/chat/message/desktop.tsx +1 -0
  227. package/src/plugins/builtin/chat/message/inline-tokens.tsx +23 -0
  228. package/src/plugins/builtin/chat/message/pane-chip.tsx +50 -20
  229. package/src/plugins/builtin/chat/pane-links/commands.ts +271 -0
  230. package/src/plugins/builtin/chat/pane-links/model.ts +12 -3
  231. package/src/plugins/builtin/chat/pane-links/open.ts +8 -1
  232. package/src/plugins/builtin/chat/unread-inbox-pane.tsx +10 -1
  233. package/src/plugins/builtin/clinical-trials/model.ts +0 -9
  234. package/src/plugins/builtin/clinical-trials/pane.tsx +15 -22
  235. package/src/plugins/builtin/clinical-trials/sponsor-tickers.ts +8 -6
  236. package/src/plugins/builtin/cloud/askg/manifest.ts +2 -0
  237. package/src/plugins/builtin/cloud/plugin.tsx +1 -1
  238. package/src/plugins/builtin/company-attention/building.tsx +5 -1
  239. package/src/plugins/builtin/company-attention/client.ts +8 -9
  240. package/src/plugins/builtin/company-attention/evidence.ts +4 -1
  241. package/src/plugins/builtin/company-attention/moves.tsx +5 -1
  242. package/src/plugins/builtin/company-attention/pane.tsx +9 -2
  243. package/src/plugins/builtin/company-attention/signals.tsx +5 -1
  244. package/src/plugins/builtin/correlation/headless.ts +13 -5
  245. package/src/plugins/builtin/correlation/history.ts +22 -0
  246. package/src/plugins/builtin/cot/client.ts +22 -18
  247. package/src/plugins/builtin/cot/headless.ts +15 -10
  248. package/src/plugins/builtin/cot/model.ts +14 -1
  249. package/src/plugins/builtin/cot/pane.tsx +22 -14
  250. package/src/plugins/builtin/credit-boards/client.ts +6 -10
  251. package/src/plugins/builtin/credit-conditions/headless.ts +8 -2
  252. package/src/plugins/builtin/credit-conditions/index.tsx +5 -1
  253. package/src/plugins/builtin/credit-conditions/model.ts +4 -0
  254. package/src/plugins/builtin/credit-conditions/series.ts +3 -1
  255. package/src/plugins/builtin/credit-documents/detail.tsx +2 -2
  256. package/src/plugins/builtin/credit-documents/export.ts +173 -0
  257. package/src/plugins/builtin/credit-documents/headless.ts +7 -7
  258. package/src/plugins/builtin/credit-documents/model.ts +104 -14
  259. package/src/plugins/builtin/credit-documents/pane.tsx +12 -5
  260. package/src/plugins/builtin/custom-view/sources.ts +2 -0
  261. package/src/plugins/builtin/dividend-yield/client.ts +131 -23
  262. package/src/plugins/builtin/dividend-yield/headless.ts +44 -16
  263. package/src/plugins/builtin/dividend-yield/model.ts +8 -5
  264. package/src/plugins/builtin/dividend-yield/pane.tsx +38 -13
  265. package/src/plugins/builtin/dividend-yield/ranking.ts +37 -14
  266. package/src/plugins/builtin/dividend-yield/types.ts +20 -2
  267. package/src/plugins/builtin/dividend-yield/view.ts +30 -2
  268. package/src/plugins/builtin/docs/targets.ts +5 -1
  269. package/src/plugins/builtin/earnings/board-model.ts +16 -15
  270. package/src/plugins/builtin/earnings/board.tsx +62 -71
  271. package/src/plugins/builtin/earnings/headless.ts +40 -4
  272. package/src/plugins/builtin/earnings/scope.ts +31 -43
  273. package/src/plugins/builtin/earnings-calls/calendar.tsx +2 -2
  274. package/src/plugins/builtin/earnings-calls/format.ts +31 -2
  275. package/src/plugins/builtin/earnings-calls/headless.ts +7 -2
  276. package/src/plugins/builtin/earnings-calls/model.ts +6 -1
  277. package/src/plugins/builtin/earnings-calls/pane.tsx +5 -4
  278. package/src/plugins/builtin/econ/calendar-model.ts +14 -9
  279. package/src/plugins/builtin/econ/figures.ts +72 -0
  280. package/src/plugins/builtin/econ/index.tsx +33 -3
  281. package/src/plugins/builtin/econ/types.ts +4 -0
  282. package/src/plugins/builtin/econ-statistics/defs.ts +6 -0
  283. package/src/plugins/builtin/econ-statistics/headless.ts +85 -35
  284. package/src/plugins/builtin/econ-statistics/stats.ts +37 -9
  285. package/src/plugins/builtin/econ-statistics/view.ts +3 -0
  286. package/src/plugins/builtin/equity-screener/categories.ts +179 -0
  287. package/src/plugins/builtin/equity-screener/client.ts +4 -2
  288. package/src/plugins/builtin/equity-screener/headless.ts +144 -13
  289. package/src/plugins/builtin/equity-screener/ideas.ts +49 -0
  290. package/src/plugins/builtin/equity-screener/model.ts +99 -10
  291. package/src/plugins/builtin/equity-screener/pane.tsx +70 -15
  292. package/src/plugins/builtin/exposure/charts.tsx +2 -2
  293. package/src/plugins/builtin/exposure/model.ts +13 -1
  294. package/src/plugins/builtin/exposure/pane.tsx +4 -4
  295. package/src/plugins/builtin/fixed-income/pane.tsx +2 -1
  296. package/src/plugins/builtin/futures/index.tsx +1 -0
  297. package/src/plugins/builtin/futures/model.ts +2 -1
  298. package/src/plugins/builtin/futures/table.tsx +2 -2
  299. package/src/plugins/builtin/futures/use-board-terms.ts +42 -28
  300. package/src/plugins/builtin/futures/use-front-returns.ts +45 -28
  301. package/src/plugins/builtin/fx-matrix/client.ts +11 -3
  302. package/src/plugins/builtin/fx-matrix/headless.ts +6 -3
  303. package/src/plugins/builtin/fx-matrix/index.tsx +16 -4
  304. package/src/plugins/builtin/fx-matrix/live-legs.ts +54 -3
  305. package/src/plugins/builtin/gpu/headless.ts +8 -2
  306. package/src/plugins/builtin/help/function-index.ts +4 -1
  307. package/src/plugins/builtin/help/index.tsx +1 -0
  308. package/src/plugins/builtin/help/keybindings-editor.tsx +18 -14
  309. package/src/plugins/builtin/help/shortcut-model.ts +1 -1
  310. package/src/plugins/builtin/holders/fund-holders.ts +51 -0
  311. package/src/plugins/builtin/holders/headless.ts +18 -1
  312. package/src/plugins/builtin/iv-history/client.ts +52 -11
  313. package/src/plugins/builtin/iv-history/format.ts +36 -23
  314. package/src/plugins/builtin/iv-history/headless.ts +36 -18
  315. package/src/plugins/builtin/iv-history/index.tsx +2 -2
  316. package/src/plugins/builtin/iv-history/model.ts +163 -27
  317. package/src/plugins/builtin/iv-history/pane.tsx +10 -6
  318. package/src/plugins/builtin/iv-history/screen-pane.tsx +22 -15
  319. package/src/plugins/builtin/iv-history/universe.ts +5 -1
  320. package/src/plugins/builtin/jobs/client.ts +25 -29
  321. package/src/plugins/builtin/kelly-sizer/model.ts +12 -8
  322. package/src/plugins/builtin/kelly-sizer/pane.tsx +9 -9
  323. package/src/plugins/builtin/kelly-sizer/sections.tsx +19 -10
  324. package/src/plugins/builtin/kelly-sizer/types.ts +10 -4
  325. package/src/plugins/builtin/macro-day/pane.tsx +7 -5
  326. package/src/plugins/builtin/macro-day/release-table.ts +2 -2
  327. package/src/plugins/builtin/market-heatmap/data.ts +8 -33
  328. package/src/plugins/builtin/market-movers/client.ts +25 -7
  329. package/src/plugins/builtin/market-movers/footer.ts +2 -2
  330. package/src/plugins/builtin/market-movers/headless.ts +32 -12
  331. package/src/plugins/builtin/market-movers/index.tsx +26 -14
  332. package/src/plugins/builtin/market-movers/min-float.ts +74 -0
  333. package/src/plugins/builtin/market-movers/model.ts +4 -1
  334. package/src/plugins/builtin/market-movers/screener.ts +14 -0
  335. package/src/plugins/builtin/market-movers/session-body.tsx +13 -8
  336. package/src/plugins/builtin/market-movers/session-table.ts +4 -3
  337. package/src/plugins/builtin/market-movers/table.ts +17 -5
  338. package/src/plugins/builtin/members/breadth-pane.tsx +82 -0
  339. package/src/plugins/builtin/members/client.ts +19 -4
  340. package/src/plugins/builtin/members/headless.ts +20 -7
  341. package/src/plugins/builtin/members/index.tsx +9 -9
  342. package/src/plugins/builtin/members/model.ts +23 -4
  343. package/src/plugins/builtin/members/pane.tsx +25 -15
  344. package/src/plugins/builtin/news/index.tsx +1 -0
  345. package/src/plugins/builtin/news/wire/categories.ts +19 -3
  346. package/src/plugins/builtin/news/wire/industry-pane.tsx +1 -0
  347. package/src/plugins/builtin/news/wire/news/footer.ts +31 -5
  348. package/src/plugins/builtin/news/wire/news/preset-pane.tsx +6 -1
  349. package/src/plugins/builtin/news/wire/news/table.tsx +2 -2
  350. package/src/plugins/builtin/openfda/client.ts +14 -2
  351. package/src/plugins/builtin/openfda/index.tsx +3 -2
  352. package/src/plugins/builtin/openfda/model.ts +9 -0
  353. package/src/plugins/builtin/openfda/pane.tsx +42 -6
  354. package/src/plugins/builtin/options/analytics.ts +54 -6
  355. package/src/plugins/builtin/options/enrichment.ts +17 -5
  356. package/src/plugins/builtin/options/model-spot.ts +5 -2
  357. package/src/plugins/builtin/options/strike-window.ts +2 -1
  358. package/src/plugins/builtin/options/table.ts +6 -9
  359. package/src/plugins/builtin/options/types.ts +2 -0
  360. package/src/plugins/builtin/options/view.tsx +42 -12
  361. package/src/plugins/builtin/options-positioning/client.ts +30 -0
  362. package/src/plugins/builtin/options-positioning/headless.ts +74 -21
  363. package/src/plugins/builtin/options-positioning/index.tsx +4 -4
  364. package/src/plugins/builtin/options-positioning/model.ts +122 -14
  365. package/src/plugins/builtin/options-positioning/pane.tsx +87 -42
  366. package/src/plugins/builtin/options-scenario/client.ts +116 -47
  367. package/src/plugins/builtin/options-scenario/csp-screen-headless.ts +142 -10
  368. package/src/plugins/builtin/options-scenario/csp-screen-pane.tsx +206 -55
  369. package/src/plugins/builtin/options-scenario/csp-screen.ts +63 -23
  370. package/src/plugins/builtin/options-scenario/csp.ts +8 -2
  371. package/src/plugins/builtin/options-scenario/index.tsx +9 -7
  372. package/src/plugins/builtin/options-scenario/strategy-screen.ts +532 -0
  373. package/src/plugins/builtin/pe-band/model.ts +12 -49
  374. package/src/plugins/builtin/perps/cascade-tabs.tsx +161 -0
  375. package/src/plugins/builtin/perps/cascade.ts +236 -0
  376. package/src/plugins/builtin/perps/client.ts +56 -2
  377. package/src/plugins/builtin/perps/freshness.ts +12 -10
  378. package/src/plugins/builtin/perps/headless.ts +65 -9
  379. package/src/plugins/builtin/perps/index.tsx +7 -5
  380. package/src/plugins/builtin/perps/live-rows.ts +10 -3
  381. package/src/plugins/builtin/perps/model.ts +18 -4
  382. package/src/plugins/builtin/perps/pane.tsx +32 -31
  383. package/src/plugins/builtin/perps/status-line.ts +25 -0
  384. package/src/plugins/builtin/plugin-module.ts +5 -1
  385. package/src/plugins/builtin/portfolio-list/cached-account.ts +3 -1
  386. package/src/plugins/builtin/portfolio-list/cli/bulk-symbols.ts +2 -8
  387. package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +4 -4
  388. package/src/plugins/builtin/portfolio-list/cli/render.ts +12 -7
  389. package/src/plugins/builtin/portfolio-list/headless.ts +1 -1
  390. package/src/plugins/builtin/portfolio-list/pane/futures-front.ts +40 -0
  391. package/src/plugins/builtin/portfolio-list/pane/index.tsx +4 -1
  392. package/src/plugins/builtin/portfolio-list/pane/streaming.ts +5 -2
  393. package/src/plugins/builtin/portfolio-list/pane/supplemental.ts +3 -2
  394. package/src/plugins/builtin/portfolio-list/quick-add/resolution.ts +3 -1
  395. package/src/plugins/builtin/portfolio-list/summary/index.tsx +11 -8
  396. package/src/plugins/builtin/portfolio-list/table.tsx +11 -3
  397. package/src/plugins/builtin/primary-dealers/client.ts +13 -38
  398. package/src/plugins/builtin/rate-path/pane.tsx +2 -2
  399. package/src/plugins/builtin/realized-vol/index.tsx +2 -2
  400. package/src/plugins/builtin/realized-vol/pane.tsx +3 -3
  401. package/src/plugins/builtin/relative-rotation/client.ts +18 -4
  402. package/src/plugins/builtin/relative-rotation/headless.ts +3 -3
  403. package/src/plugins/builtin/relative-rotation/index.tsx +2 -1
  404. package/src/plugins/builtin/relative-rotation/model.ts +16 -40
  405. package/src/plugins/builtin/relative-rotation/pane.tsx +3 -2
  406. package/src/plugins/builtin/research/corporate-actions-pane.tsx +3 -2
  407. package/src/plugins/builtin/research/event-model.ts +10 -8
  408. package/src/plugins/builtin/research/headless.ts +1 -1
  409. package/src/plugins/builtin/research/relative-valuation-headless.ts +5 -1
  410. package/src/plugins/builtin/research/relative-valuation-model.ts +31 -3
  411. package/src/plugins/builtin/research/relative-valuation-pane.tsx +11 -9
  412. package/src/plugins/builtin/reverse-dcf/headless.ts +5 -3
  413. package/src/plugins/builtin/reverse-dcf/model.ts +61 -6
  414. package/src/plugins/builtin/reverse-dcf/pane.tsx +7 -4
  415. package/src/plugins/builtin/scanner/feed.ts +2 -2
  416. package/src/plugins/builtin/scanner/flow-model.ts +50 -4
  417. package/src/plugins/builtin/scanner/flow-pane.tsx +367 -65
  418. package/src/plugins/builtin/scanner/flow-session.ts +146 -0
  419. package/src/plugins/builtin/scanner/headless.ts +204 -35
  420. package/src/plugins/builtin/scanner/index.ts +40 -6
  421. package/src/plugins/builtin/scanner/live-condition-editor.tsx +222 -0
  422. package/src/plugins/builtin/scanner/live-feed.ts +168 -0
  423. package/src/plugins/builtin/scanner/live-headless.ts +138 -0
  424. package/src/plugins/builtin/scanner/live-model.ts +362 -0
  425. package/src/plugins/builtin/scanner/live-pane.tsx +677 -0
  426. package/src/plugins/builtin/scanner/live-track.ts +186 -0
  427. package/src/plugins/builtin/scanner/lock-note.ts +3 -2
  428. package/src/plugins/builtin/seasonality/headless.ts +10 -1
  429. package/src/plugins/builtin/sec/fund-facts-view.tsx +5 -2
  430. package/src/plugins/builtin/sec/fund-facts.ts +116 -34
  431. package/src/plugins/builtin/sec/headless.ts +2 -1
  432. package/src/plugins/builtin/series-inventory.ts +3 -0
  433. package/src/plugins/builtin/shared/cloud-resource.ts +3 -2
  434. package/src/plugins/builtin/shared/cloud-upgrade.ts +4 -3
  435. package/src/plugins/builtin/shared/earnings-calendar.ts +6 -2
  436. package/src/plugins/builtin/shared/earnings-report.ts +2 -2
  437. package/src/plugins/builtin/shared/job-posting.ts +1 -0
  438. package/src/plugins/builtin/shared/macro-releases.ts +65 -0
  439. package/src/plugins/builtin/shared/members-menu.tsx +3 -2
  440. package/src/plugins/builtin/shared/pro-lock-note.ts +12 -12
  441. package/src/plugins/builtin/shared/report-freshness.ts +3 -2
  442. package/src/plugins/builtin/shared/scanner-capture.ts +3 -0
  443. package/src/plugins/builtin/shared/ticker-choice.tsx +2 -1
  444. package/src/plugins/builtin/shared/ticker-company.ts +77 -0
  445. package/src/plugins/builtin/shared/use-quote-board.ts +10 -3
  446. package/src/plugins/builtin/shared/volatility/live-session.ts +34 -8
  447. package/src/plugins/builtin/shared/volatility/pricing.ts +26 -1
  448. package/src/plugins/builtin/shared/wall-view-lifecycle.ts +3 -1
  449. package/src/plugins/builtin/themes/headless.ts +6 -4
  450. package/src/plugins/builtin/themes/model.ts +17 -8
  451. package/src/plugins/builtin/themes/pane.tsx +7 -7
  452. package/src/plugins/builtin/ticker-detail/data-panes/historical-prices.tsx +43 -18
  453. package/src/plugins/builtin/ticker-detail/data-panes/returns-history.ts +3 -2
  454. package/src/plugins/builtin/ticker-detail/data-panes/returns-model.ts +62 -0
  455. package/src/plugins/builtin/ticker-detail/data-panes/returns-pane.tsx +83 -46
  456. package/src/plugins/builtin/ticker-detail/headless.ts +31 -16
  457. package/src/plugins/builtin/ticker-detail/overview/model.ts +1 -1
  458. package/src/plugins/builtin/ticker-detail/pane.tsx +3 -2
  459. package/src/plugins/builtin/ticker-detail/quote-footer.ts +6 -1
  460. package/src/plugins/builtin/ticker-detail/quote-monitor/index.tsx +2 -1
  461. package/src/plugins/builtin/ticker-detail/settings.ts +1 -0
  462. package/src/plugins/builtin/time-sales/pane.tsx +31 -19
  463. package/src/plugins/builtin/treasury-daily/client.ts +41 -5
  464. package/src/plugins/builtin/treasury-daily/headless.ts +2 -2
  465. package/src/plugins/builtin/treasury-daily/index.tsx +1 -1
  466. package/src/plugins/builtin/treasury-daily/model.ts +50 -3
  467. package/src/plugins/builtin/treasury-daily/pane.tsx +81 -2
  468. package/src/plugins/builtin/vol-surface/charts.tsx +9 -4
  469. package/src/plugins/builtin/vol-surface/client.ts +9 -17
  470. package/src/plugins/builtin/vol-surface/headless.ts +63 -14
  471. package/src/plugins/builtin/vol-surface/index.tsx +2 -2
  472. package/src/plugins/builtin/vol-surface/model.ts +22 -7
  473. package/src/plugins/builtin/vol-surface/pane.tsx +48 -9
  474. package/src/plugins/builtin/vol-surface/tables.ts +31 -3
  475. package/src/plugins/builtin/volatility/dvol.ts +46 -0
  476. package/src/plugins/builtin/volatility/index.tsx +2 -2
  477. package/src/plugins/builtin/volatility/pane.tsx +4 -4
  478. package/src/plugins/builtin/volatility/series.ts +26 -0
  479. package/src/plugins/builtin/world-indices/footer.ts +1 -1
  480. package/src/plugins/builtin/world-venue-map/headless.ts +3 -3
  481. package/src/plugins/catalog-browser.ts +13 -8
  482. package/src/plugins/catalog-manifest.ts +2 -1
  483. package/src/plugins/marketplace/model.ts +18 -5
  484. package/src/portfolio/column-values.ts +5 -5
  485. package/src/portfolio/futures-positions.ts +6 -3
  486. package/src/portfolio/position-quantity.ts +15 -9
  487. package/src/public/__snapshots__/public-api.test.ts.snap +1 -0
  488. package/src/remote/resources.ts +2 -1
  489. package/src/renderers/browser/app-services.ts +1 -7
  490. package/src/renderers/browser/config-host.ts +2 -55
  491. package/src/renderers/browser/main.tsx +7 -57
  492. package/src/renderers/dom/data-table/row.tsx +26 -0
  493. package/src/renderers/dom/desktop/list-view.tsx +13 -10
  494. package/src/renderers/dom/desktop/query-bar.tsx +4 -2
  495. package/src/renderers/dom/desktop/select-field.tsx +4 -2
  496. package/src/renderers/dom/host/chart-surface.tsx +21 -0
  497. package/src/renderers/electrobun/bun/desktop/app-name.ts +222 -0
  498. package/src/renderers/electrobun/bun/desktop/backend.ts +29 -7
  499. package/src/renderers/electrobun/bun/desktop/host-requests.ts +7 -0
  500. package/src/renderers/electrobun/bun/desktop/initialization.ts +2 -0
  501. package/src/renderers/electrobun/bun/desktop/relaunch.ts +74 -25
  502. package/src/renderers/electrobun/bun/desktop/state-broadcaster.ts +1 -0
  503. package/src/renderers/electrobun/bun/desktop/update.ts +173 -5
  504. package/src/renderers/electrobun/bun/desktop/view-ids.ts +52 -0
  505. package/src/renderers/electrobun/bun/desktop/workspace/index.ts +2 -0
  506. package/src/renderers/electrobun/bun/index.ts +25 -1
  507. package/src/renderers/electrobun/shared/app-name.ts +30 -0
  508. package/src/renderers/electrobun/shared/protocol.ts +10 -0
  509. package/src/renderers/electrobun/view/backend-rpc.ts +6 -0
  510. package/src/renderers/electrobun/view/cli-pane-shot-frame.tsx +3 -3
  511. package/src/renderers/electrobun/view/desktop/window/snapshot.ts +1 -0
  512. package/src/renderers/electrobun/view/main.tsx +24 -1
  513. package/src/renderers/electrobun/view/news-source.ts +3 -1
  514. package/src/renderers/electrobun/view/remote/ticker-repository.ts +14 -7
  515. package/src/renderers/electrobun/view/view-ids.ts +85 -0
  516. package/src/renderers/opentui/start.tsx +5 -0
  517. package/src/renderers/opentui/toast-host.tsx +71 -43
  518. package/src/series/registry.ts +1 -0
  519. package/src/series/types.ts +6 -0
  520. package/src/series/validate.ts +1 -0
  521. package/src/sources/gloomberb-cloud/index.ts +1 -0
  522. package/src/sources/gloomberb-cloud/news.ts +47 -7
  523. package/src/sources/gloomberb-cloud/normalizers.ts +2 -0
  524. package/src/sources/provider-router/batches.ts +10 -2
  525. package/src/sources/provider-router/financial-routes.ts +3 -3
  526. package/src/sources/provider-router/financials.ts +15 -3
  527. package/src/sources/provider-router/history.ts +28 -7
  528. package/src/sources/provider-router/index.ts +149 -10
  529. package/src/sources/provider-router/search.ts +13 -2
  530. package/src/state/app/context/index.tsx +3 -0
  531. package/src/state/ticker-cleanup.ts +50 -0
  532. package/src/sync/auth-transition.ts +19 -9
  533. package/src/sync/baseline.ts +10 -4
  534. package/src/sync/controller.ts +70 -19
  535. package/src/sync/core-contributors.ts +90 -31
  536. package/src/sync/react.ts +4 -1
  537. package/src/sync/types.ts +3 -0
  538. package/src/telemetry/stall-reports-dom.ts +38 -0
  539. package/src/telemetry/stall-reports-node.ts +75 -0
  540. package/src/telemetry/stall-reports.ts +214 -0
  541. package/src/telemetry/usage-counts.ts +0 -18
  542. package/src/test-support/preload.ts +14 -0
  543. package/src/theme/colors.ts +8 -0
  544. package/src/theme/themes.ts +10 -0
  545. package/src/tickers/company-name.ts +103 -3
  546. package/src/tickers/listing-venues.ts +38 -3
  547. package/src/tickers/search/bare-symbol.ts +36 -0
  548. package/src/tickers/search/index.ts +36 -7
  549. package/src/tickers/search/ranking.ts +10 -1
  550. package/src/tickers/search/types.ts +5 -0
  551. package/src/tickers/terminal-codes.ts +19 -0
  552. package/src/time-series/alignment.ts +1 -1
  553. package/src/time-series/base-series.ts +13 -5
  554. package/src/time-series/daily-valuation.ts +62 -0
  555. package/src/time-series/economic.ts +18 -4
  556. package/src/time-series/field-catalog.ts +2 -4
  557. package/src/time-series/filed-trailing-eps.ts +197 -0
  558. package/src/time-series/forward-valuation.ts +32 -0
  559. package/src/time-series/fundamentals.ts +198 -7
  560. package/src/time-series/hooks.ts +1 -0
  561. package/src/time-series/ice-credit.ts +3 -0
  562. package/src/time-series/price-comparison.ts +30 -2
  563. package/src/time-series/price-units.ts +72 -2
  564. package/src/time-series/resolve-context.ts +7 -1
  565. package/src/time-series/resolve.ts +116 -15
  566. package/src/time-series/series-presentation.ts +40 -6
  567. package/src/time-series/session-bar.ts +11 -0
  568. package/src/time-series/spec.ts +5 -3
  569. package/src/time-series/studies.ts +278 -74
  570. package/src/time-series/total-return.ts +160 -0
  571. package/src/time-series/transforms.ts +3 -3
  572. package/src/time-series/types.ts +27 -1
  573. package/src/time-series/valuation-releases.ts +39 -0
  574. package/src/types/data-provider.ts +9 -1
  575. package/src/types/desktop-window.ts +2 -0
  576. package/src/types/financials.ts +73 -2
  577. package/src/types/headless.ts +61 -5
  578. package/src/types/instrument.ts +3 -0
  579. package/src/types/news-source.ts +1 -0
  580. package/src/types/plugin.ts +10 -1
  581. package/src/ui/host.tsx +3 -0
  582. package/src/updater/command-names.ts +12 -7
  583. package/src/updater/failure.ts +4 -1
  584. package/src/utils/cli-output.ts +42 -1
  585. package/src/utils/crypto-pair.ts +44 -0
  586. package/src/utils/financial-statements.ts +6 -1
  587. package/src/utils/forward-dividend.ts +2 -0
  588. package/src/utils/fundamentals.ts +24 -3
  589. package/src/utils/fx-market-hours.ts +26 -3
  590. package/src/utils/main-thread-stall.ts +35 -2
  591. package/src/utils/market-capitalization.ts +24 -1
  592. package/src/utils/network-failure.ts +9 -6
  593. package/src/utils/option-expiry.ts +48 -1
  594. package/src/utils/options.ts +10 -0
  595. package/src/utils/plugin-proxy-hosts.json +1 -0
  596. package/src/utils/price-history.ts +12 -1
  597. package/src/utils/shell-word.ts +8 -0
  598. package/src/utils/trailing-dividend.ts +53 -4
  599. package/src/plugins/builtin/clinical-trials/ticker-sponsor.ts +0 -17
  600. package/src/renderers/browser/first-screen.ts +0 -193
package/README.md CHANGED
@@ -53,7 +53,7 @@ With [Bun](https://bun.sh), on any supported OS:
53
53
  bun install -g gloomberb
54
54
  ```
55
55
 
56
- Then run `gloom`. The command was called `gloomberb` before 0.19, and that name still works. For chart graphics, use a Kitty-compatible terminal such as Ghostty, Kitty, or WezTerm. Windows Terminal draws charts as text; the desktop app draws them in full.
56
+ Then run `gloom`. The command was called `gloomberb` before 0.18.4, and that name still works. For chart graphics, use a Kitty-compatible terminal such as Ghostty, Kitty, or WezTerm. Windows Terminal draws charts as text; the desktop app draws them in full.
57
57
 
58
58
  ## Start
59
59
 
package/README.zh-CN.md CHANGED
@@ -65,7 +65,7 @@ curl -fsSL gloom.sh/install | bash
65
65
  bun install -g gloomberb
66
66
  ```
67
67
 
68
- 运行 `gloom` 即可启动。0.19 之前命令名为 `gloomberb`,该名称仍可使用。要显示图形,请使用兼容 Kitty 图形协议的终端,例如 Ghostty、Kitty 或 WezTerm。直接下载、安装位置与更新方式详见[安装指南(英文)](docs/installation.md)。
68
+ 运行 `gloom` 即可启动。0.18.4 之前命令名为 `gloomberb`,该名称仍可使用。要显示图形,请使用兼容 Kitty 图形协议的终端,例如 Ghostty、Kitty 或 WezTerm。直接下载、安装位置与更新方式详见[安装指南(英文)](docs/installation.md)。
69
69
 
70
70
  ## 开始使用
71
71
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gloomberb",
3
- "version": "0.18.4",
3
+ "version": "0.19.0",
4
4
  "packageManager": "bun@1.3.11",
5
5
  "description": "Market research and portfolio tracker for the terminal",
6
6
  "module": "src/public/index.ts",
@@ -74,7 +74,7 @@ index cdaa2bca0fabe577cb667056aa6f8f84211189c2..3839e5232742c2467180c344f51a30f1
74
74
 
75
75
  // Encrypt function
76
76
  diff --git a/dist/api/bun/core/Updater.ts b/dist/api/bun/core/Updater.ts
77
- index 39daf6d341780af8e30c2c50327162863f5977ec..0174d2ce1a9a4fa8ae0fd97367293fc5a794286a 100644
77
+ index 39daf6d341780af8e30c2c50327162863f5977ec..4f3d2bef8e4b41a13a5a522c0af8dd700879a5db 100644
78
78
  --- a/dist/api/bun/core/Updater.ts
79
79
  +++ b/dist/api/bun/core/Updater.ts
80
80
  @@ -132,6 +132,19 @@ let updateInfo: {
@@ -193,7 +193,52 @@ index 39daf6d341780af8e30c2c50327162863f5977ec..0174d2ce1a9a4fa8ae0fd97367293fc5
193
193
  emitStatus(
194
194
  "fetching-patch",
195
195
  `Checking for patch: ${currentHash.slice(0, 8)}`,
196
- @@ -612,12 +679,12 @@ const Updater = {
196
+ @@ -498,11 +565,25 @@ const Updater = {
197
+ // - macOS/Windows: Resources/version.json (inside the app bundle directory)
198
+ // - Linux: metadata.json (alongside the app bundle)
199
+ const resourcesDir = "Resources";
200
+ - const patchedTarBytes = await Bun.file(
201
+ - tmpPatchedTarFilePath,
202
+ - ).arrayBuffer();
203
+ - const patchedArchive = new Bun.Archive(patchedTarBytes);
204
+ - const patchedFiles = await patchedArchive.files();
205
+ + let patchedFiles: Map<string, File>;
206
+ + try {
207
+ + const patchedTarBytes = await Bun.file(
208
+ + tmpPatchedTarFilePath,
209
+ + ).arrayBuffer();
210
+ + const patchedArchive = new Bun.Archive(patchedTarBytes);
211
+ + patchedFiles = await patchedArchive.files();
212
+ + } catch (error) {
213
+ + // bspatch does not check what it patches: from a damaged tar it
214
+ + // makes one that does not read, and would at every retry. The
215
+ + // full download replaces both.
216
+ + const message = error instanceof Error ? error.message : String(error);
217
+ + emitStatus("patch-failed", `Patched tar does not read: ${message}`, {
218
+ + currentHash,
219
+ + errorMessage: message,
220
+ + });
221
+ + console.error("patched tar does not read", error);
222
+ + break;
223
+ + }
224
+
225
+ for (const [filePath] of patchedFiles) {
226
+ if (
227
+ @@ -528,8 +609,11 @@ const Updater = {
228
+ }
229
+
230
+ const hashFile = patchedFiles.get(hashFilePath);
231
+ - const hashFileJson = JSON.parse(await hashFile!.text());
232
+ - const nextHash = hashFileJson.hash;
233
+ + // Unreadable, it has no hash below and the full download follows.
234
+ + const nextHash: string = await hashFile!
235
+ + .text()
236
+ + .then((text) => JSON.parse(text)?.hash)
237
+ + .catch(() => "");
238
+
239
+ if (seenHashes.includes(nextHash)) {
240
+ emitStatus(
241
+ @@ -612,12 +696,12 @@ const Updater = {
197
242
 
198
243
  const cacheBuster = Math.random().toString(36).substring(7);
199
244
  const platformPrefix = getPlatformPrefix(
@@ -208,7 +253,65 @@ index 39daf6d341780af8e30c2c50327162863f5977ec..0174d2ce1a9a4fa8ae0fd97367293fc5
208
253
  const prevVersionCompressedTarballPath = join(
209
254
  appDataFolder,
210
255
  "self-extraction",
211
- @@ -760,7 +827,12 @@ const Updater = {
256
+ @@ -689,6 +773,13 @@ const Updater = {
257
+ emitStatus("error", updateInfo.error, { zstdPath });
258
+ console.error("zig-zstd not found:", zstdPath);
259
+ } else {
260
+ + // Into a name of its own, renamed once whole: zig-zstd writes as
261
+ + // it goes, and a run that failed (a download cut short) or never
262
+ + // finished (the app quit) left part of a tar under the update's
263
+ + // own name, which every later download took as done and every
264
+ + // install then failed to unpack.
265
+ + const partialTarPath = `${latestTarPath}.partial`;
266
+ + rmSync(partialTarPath, { force: true });
267
+ const decompressResult = Bun.spawnSync(
268
+ [
269
+ zstdPath,
270
+ @@ -696,7 +787,7 @@ const Updater = {
271
+ "-i",
272
+ prevVersionCompressedTarballPath,
273
+ "-o",
274
+ - latestTarPath,
275
+ + partialTarPath,
276
+ "--no-timing",
277
+ ],
278
+ {
279
+ @@ -706,6 +797,7 @@ const Updater = {
280
+ },
281
+ );
282
+ if (!decompressResult.success) {
283
+ + rmSync(partialTarPath, { force: true });
284
+ updateInfo.error = `zig-zstd failed with exit code ${decompressResult.exitCode}`;
285
+ emitStatus("error", updateInfo.error, {
286
+ zstdPath,
287
+ @@ -716,6 +808,7 @@ const Updater = {
288
+ zstdPath,
289
+ });
290
+ } else {
291
+ + renameSync(partialTarPath, latestTarPath);
292
+ emitStatus("decompressing", "Decompression complete");
293
+ }
294
+ }
295
+ @@ -731,6 +824,8 @@ const Updater = {
296
+ // check for patch from that tar and apply it, until it matches the latest version
297
+ // as a fallback it should just download and unpack the latest version
298
+ updateInfo.updateReady = true;
299
+ + // What failed on the way (a patch that did not apply) was recovered from.
300
+ + updateInfo.error = "";
301
+ emitStatus(
302
+ "download-complete",
303
+ `Update ready to install (used ${usedPatchPath ? "patch" : "full download"} path)`,
304
+ @@ -741,7 +836,8 @@ const Updater = {
305
+ },
306
+ );
307
+ } else {
308
+ - updateInfo.error = "Failed to download latest version";
309
+ + // Why it failed (zig-zstd's exit), when that is known.
310
+ + if (!updateInfo.error) updateInfo.error = "Failed to download latest version";
311
+ emitStatus("error", "Failed to download latest version", { latestHash });
312
+ }
313
+
314
+ @@ -760,7 +856,12 @@ const Updater = {
212
315
  mkdirSync(extractionFolder, { recursive: true });
213
316
  }
214
317
 
@@ -222,7 +325,37 @@ index 39daf6d341780af8e30c2c50327162863f5977ec..0174d2ce1a9a4fa8ae0fd97367293fc5
222
325
  const latestTarPath = join(extractionFolder, `${latestHash}.tar`);
223
326
 
224
327
  let appBundleSubpath: string = "";
225
- @@ -894,14 +966,7 @@ const Updater = {
328
+ @@ -782,9 +883,26 @@ const Updater = {
329
+ mkdirSync(extractionDir, { recursive: true });
330
+ }
331
+
332
+ - const latestTarBytes = await Bun.file(latestTarPath).arrayBuffer();
333
+ - const latestArchive = new Bun.Archive(latestTarBytes);
334
+ - await latestArchive.extract(extractionDir);
335
+ + try {
336
+ + const latestTarBytes = await Bun.file(latestTarPath).arrayBuffer();
337
+ + const latestArchive = new Bun.Archive(latestTarBytes);
338
+ + await latestArchive.extract(extractionDir);
339
+ + } catch (error) {
340
+ + // The tar goes, with what it unpacked: left in place, every later
341
+ + // download took it as the update again and every install failed
342
+ + // here the same way. The next download fetches a fresh copy.
343
+ + const message = `Failed to extract update: ${error instanceof Error ? error.message : String(error)}`;
344
+ + try {
345
+ + rmSync(latestTarPath, { force: true });
346
+ + } catch (e) {
347
+ + // Best effort, like the cleanup below.
348
+ + }
349
+ + cleanupExtractionFolder(extractionFolder, latestHash);
350
+ + updateInfo.updateReady = false;
351
+ + emitStatus("error", message, { errorMessage: message });
352
+ + console.error("Failed to extract update", error);
353
+ + return;
354
+ + }
355
+
356
+ if (currentOS === "macos") {
357
+ // Find the .app bundle by scanning extracted directory
358
+ @@ -894,14 +1012,7 @@ const Updater = {
226
359
  emitStatus("replacing-app", "Removing old version...");
227
360
 
228
361
  if (currentOS === "macos") {
@@ -238,7 +371,7 @@ index 39daf6d341780af8e30c2c50327162863f5977ec..0174d2ce1a9a4fa8ae0fd97367293fc5
238
371
 
239
372
  // Remove quarantine extended attributes to prevent "damaged" error
240
373
  // The inner bundle is already signed/notarized, but macOS applies
241
- @@ -918,14 +983,7 @@ const Updater = {
374
+ @@ -918,14 +1029,7 @@ const Updater = {
242
375
  // On Linux, we now have directory bundles instead of AppImage files
243
376
  // The app is stored in {appDataFolder}/app/
244
377
  const appBundleDir = join(appDataFolder, "app");
@@ -254,6 +387,37 @@ index 39daf6d341780af8e30c2c50327162863f5977ec..0174d2ce1a9a4fa8ae0fd97367293fc5
254
387
 
255
388
  // Ensure launcher binary is executable
256
389
  const launcherPath = join(appBundleDir, "bin", "launcher");
390
+ @@ -1071,14 +1175,18 @@ del "%~f0"
391
+ // current process has exited first. The detached shell survives our
392
+ // exit and polls until the process is gone.
393
+ const pid = process.pid;
394
+ + // The shell, sleep and open by their full paths, from /: a terminal
395
+ + // launch can hand the app a PATH without them, and a spawn into a
396
+ + // folder that is gone fails as if the shell were missing.
397
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
398
+ Bun.spawn(
399
+ [
400
+ - "sh",
401
+ + "/bin/sh",
402
+ "-c",
403
+ - `while kill -0 ${pid} 2>/dev/null; do sleep 0.5; done; sleep 1; open "${runningAppBundlePath}"`,
404
+ + `while kill -0 ${pid} 2>/dev/null; do /bin/sleep 0.5; done; /bin/sleep 1; /usr/bin/open "${runningAppBundlePath}"`,
405
+ ],
406
+ {
407
+ + cwd: "/",
408
+ detached: true,
409
+ stdio: ["ignore", "ignore", "ignore"],
410
+ } as any,
411
+ @@ -1087,7 +1195,8 @@ del "%~f0"
412
+ // On Linux, launch the launcher binary inside the app directory
413
+ const launcherPath = join(runningAppBundlePath, "bin", "launcher");
414
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
415
+ - Bun.spawn(["sh", "-c", `"${launcherPath}" &`], {
416
+ + Bun.spawn(["/bin/sh", "-c", `"${launcherPath}" &`], {
417
+ + cwd: "/",
418
+ detached: true,
419
+ } as any);
420
+ }
257
421
  diff --git a/dist/api/bun/preload/.generated/compiled.ts b/dist/api/bun/preload/.generated/compiled.ts
258
422
  index 3ab1d7d8de8938ae60823650fd3a29b952a76cb6..e0e841e6a87ce41533c6bdda8d29400aaf478e31 100644
259
423
  --- a/dist/api/bun/preload/.generated/compiled.ts
@@ -125,13 +125,17 @@ export async function performEmailAuth(mode: AccountMode, email: string, passwor
125
125
  } else {
126
126
  user = await apiClient.signIn(email, password);
127
127
  }
128
- if (!user.emailVerified) {
129
- await apiClient.sendVerification().catch(logFailure("account-auth", "Verification email request failed"));
130
- }
128
+ if (apiClient.getCurrentUser()?.id !== user.id) throw new Error("Another sign-in replaced this request.");
131
129
  const sessionToken = apiClient.getSessionToken();
132
130
  if (sessionToken) {
133
131
  chatController.adoptSession(sessionToken, user);
134
132
  }
133
+ if (!user.emailVerified) {
134
+ await apiClient.sendVerification().catch(logFailure("account-auth", "Verification email request failed"));
135
+ }
136
+ if (apiClient.getSessionToken() !== sessionToken || apiClient.getCurrentUser()?.id !== user.id) {
137
+ throw new Error("Another sign-in replaced this request.");
138
+ }
135
139
  identifyResearchUser();
136
140
  await chatController.refreshSession().catch(logFailure("account-auth", "Session refresh after email authentication failed"));
137
141
  return user;
@@ -74,6 +74,7 @@ export class CloudAuthApi {
74
74
  username: string,
75
75
  name: string,
76
76
  password: string,
77
+ isCurrent: () => boolean = () => true,
77
78
  ): Promise<AuthUser> {
78
79
  const result = await this.options.request<{ user: AuthUser }>(
79
80
  "/auth/sign-up/email",
@@ -81,7 +82,9 @@ export class CloudAuthApi {
81
82
  method: "POST",
82
83
  body: JSON.stringify({ email, username, name, password }),
83
84
  },
85
+ isCurrent,
84
86
  );
87
+ if (!isCurrent()) throw new Error("Another sign-in replaced this request.");
85
88
  this.options.requireCapturedSession(
86
89
  "Account created, but Gloom could not save the login session. Please try logging in again.",
87
90
  );
@@ -89,14 +92,16 @@ export class CloudAuthApi {
89
92
  return result.user;
90
93
  }
91
94
 
92
- async signIn(email: string, password: string): Promise<AuthUser> {
95
+ async signIn(email: string, password: string, isCurrent: () => boolean = () => true): Promise<AuthUser> {
93
96
  const result = await this.options.request<{ user: AuthUser }>(
94
97
  "/auth/sign-in/email",
95
98
  {
96
99
  method: "POST",
97
100
  body: JSON.stringify({ email, password }),
98
101
  },
102
+ isCurrent,
99
103
  );
104
+ if (!isCurrent()) throw new Error("Another sign-in replaced this request.");
100
105
  this.options.requireCapturedSession(
101
106
  "Logged in, but Gloom could not save the login session. Please try again.",
102
107
  );
@@ -127,11 +132,11 @@ export class CloudAuthApi {
127
132
  });
128
133
  }
129
134
 
130
- async signOut(): Promise<void> {
135
+ async signOut(isCurrent: () => boolean = () => true): Promise<void> {
131
136
  try {
132
- await this.options.request("/auth/sign-out", { method: "POST" });
137
+ await this.options.request("/auth/sign-out", { method: "POST" }, isCurrent);
133
138
  } finally {
134
- this.options.setSessionToken(null);
139
+ if (isCurrent()) this.options.setSessionToken(null);
135
140
  }
136
141
  }
137
142
 
@@ -1,6 +1,7 @@
1
1
  type QuoteMatchMode = "exact" | "whitespace" | "normalized"
2
2
 
3
- export const CATALYST_TYPES = ["regulatory", "clinical", "litigation", "antitrust", "recall", "sanctions", "export_control", "tariff", "rulemaking", "approval", "advisory", "pdufa"] as const
3
+ /** Regulator events, then the ones a company or its exchange dates itself (results, meetings, deals). */
4
+ export const CATALYST_TYPES = ["regulatory", "clinical", "litigation", "antitrust", "recall", "sanctions", "export_control", "tariff", "rulemaking", "approval", "advisory", "pdufa", "results", "shareholder_meeting", "merger_vote", "deal_closing", "investor_day"] as const
4
5
  export type CatalystType = (typeof CATALYST_TYPES)[number]
5
6
  type DatePrecision = "day" | "month" | "year"
6
7
  interface CatalystIdentifiers {
@@ -1,5 +1,9 @@
1
- export type CotFamily = "legacy" | "disaggregated"
1
+ /** The CFTC report: Legacy, Disaggregated, or Traders in Financial Futures (TFF). */
2
+ export type CotFamily = "legacy" | "disaggregated" | "tff"
2
3
  export type CotClass = "noncommercial" | "commercial" | "producer" | "swap" | "managed-money" | "other-reportable" | "nonreportable"
4
+ | "dealer" | "asset-manager" | "leveraged-funds"
5
+ /** Futures positions alone, or futures and options combined (options delta-adjusted, as the CFTC reports them). */
6
+ export type CotPositions = "futures-only" | "combined"
3
7
  interface CotPosition { long: number | null; short: number | null; spreading: number | null }
4
8
  interface CotPercentile {
5
9
  value: number | null
@@ -34,7 +38,7 @@ interface CotMarket {
34
38
  }
35
39
  export interface CotPayloadBase {
36
40
  source: "CFTC"
37
- scope: "futures-only"
41
+ scope: CotPositions
38
42
  reportFamily: CotFamily
39
43
  generatedAt: string
40
44
  /** Tuesday position observation date, distinct from publication/download time. */
@@ -26,7 +26,10 @@ export interface CreditFact {
26
26
  status: "active" | "superseded" | "pending";
27
27
  supersedesId: string | null;
28
28
  }
29
+ /** The party an instrument, covenant or wall bucket is of, when the filing names one other than the issuer. */
30
+ export interface CreditObligor { name: string; role?: string | null }
29
31
  export interface CreditInstrument {
32
+ obligor?: CreditObligor | null;
30
33
  lifecycle?: string | null;
31
34
  id: string;
32
35
  key: string;
@@ -41,6 +44,7 @@ export interface CreditInstrument {
41
44
  history?: CreditFact[];
42
45
  }
43
46
  export interface CreditHeadroom {
47
+ obligor?: CreditObligor | null;
44
48
  id: string;
45
49
  instrumentId: string;
46
50
  instrumentName: string;
@@ -57,12 +61,14 @@ export interface CreditHeadroom {
57
61
  evidenceIds: string[];
58
62
  }
59
63
  export interface CreditMaturityBucket {
64
+ obligor?: CreditObligor | null;
60
65
  year: number;
61
66
  currency: string;
62
67
  principal: number;
63
68
  instruments: Array<{ id: string; name: string; principal: number; evidenceIds: string[] }>;
64
69
  }
65
70
  interface CreditControlExposure {
71
+ obligor?: CreditObligor | null;
66
72
  instrumentId: string;
67
73
  instrumentName: string;
68
74
  currency: string | null;
@@ -7,7 +7,7 @@ import { companyDisclosurePath } from "./company-kpis";
7
7
  import { cloudExchangeAnnouncementsPath } from "./exchange-announcements";
8
8
  import type { PowerBoard, PowerDetail, PowerFilter, PowerHistory } from "./power";
9
9
  import type { PerpBoardPayload, PerpEquitiesPayload, PerpEquityListing, PerpHistoryPayload, PerpRankingsPayload, PerpBoardQuery, PerpHistoryQuery,
10
- PerpMarketPayload } from "./perps";
10
+ PerpMarketPayload, PerpLiquidationsPayload, PerpDepthPayload } from "./perps";
11
11
  import type { ExposureRequest, ExposurePayload, ExposureScenario } from "./exposure";
12
12
  import type { SupplyChainPayload, SupplyOptions } from "./supply-chain";
13
13
  import { supplyGraphQuery, type GraphOptions, type GraphPayload } from "./supply-chain-graph";
@@ -44,13 +44,14 @@ import type { BeneficialOwnersPayload, CloudBeneficialOwnersParams } from "./ben
44
44
  import type { CloudInsiderSignalsParams, InsiderSignalsPayload } from "./insider-signals";
45
45
  import type { SocialMentionDayPosts, SocialMentionsPayload, SocialMentionsRange } from "./social-mentions";
46
46
  import type { FuturesContractTermsPayload, FuturesCurveAsOfPayload, FuturesCurvePayload } from "./futures-curve";
47
- import type { CotBoardPayload, CotContractPayload, CotFamily, CotClass } from "./cot";
47
+ import type { CotBoardPayload, CotContractPayload, CotFamily, CotClass, CotPositions } from "./cot";
48
48
  import type { DoeBoardPayload, DoePricesPayload } from "./doe";
49
49
  import type { JodiBoardPayload, PsdBoardPayload } from "./commodity-balances";
50
50
  import type { CarbonBoard, CarbonHistory, EuropePowerBoard, EuropePowerHistory, GasStorageBoard, GasStorageHistory, GasStorageSeasonal } from "./europe-energy";
51
51
  import type { GpuBoardPayload, GpuEventsPayload, GpuHistoryPayload, GpuHistoryQuery } from "./gpu";
52
52
  import type { CpiBoardPayload } from "./cpi";
53
53
  import type { TapeRange, TapeSnapshot } from "./tape";
54
+ import { LIVE_SCAN_PATH, type LiveScanPayload, type LiveScanWireDefinition } from "./live-scan";
54
55
  import { signalWithTimeout } from "../utils/async-deadline";
55
56
  import { ApiRequestError } from "./errors";
56
57
  import type { ExchangeRateSnapshot } from "../types/exchange-rate";
@@ -179,6 +180,7 @@ import type {
179
180
  CloudWorldVenueMapPayload,
180
181
  CloudYieldPointPayload,
181
182
  ScannerFlowHistoryPage,
183
+ ScannerFlowSession,
182
184
  } from "./types";
183
185
  import type { CloudApiRequest } from "./request";
184
186
 
@@ -253,6 +255,10 @@ export class CloudDataApi {
253
255
  return this.request<import("./fund-facts").FundFactsPayload>(`/cloud/fund-facts/${encodeURIComponent(ticker)}`, options.signal ? { signal: options.signal } : undefined);
254
256
  }
255
257
 
258
+ getFundBreadth(fund: string) {
259
+ return this.request<import("./members").FundBreadthPayload>(`/cloud/members/${encodeURIComponent(fund)}/breadth`);
260
+ }
261
+
256
262
  getFundChanges(fund: string) {
257
263
  return this.request<import("./members").FundChangesPayload>(`/cloud/members/${encodeURIComponent(fund)}/changes`);
258
264
  }
@@ -589,12 +595,15 @@ export class CloudDataApi {
589
595
  return this.request<CloudShillerPayload>(cloudShillerPath());
590
596
  }
591
597
 
592
- async getCloudCotBoard(report: CotFamily, traderClass: CotClass): Promise<CotBoardPayload> {
593
- return this.request<CotBoardPayload>(`/cloud/cot/board?${new URLSearchParams({ report, traderClass })}`);
598
+ /** Futures-only positions unless `positions` asks for futures and options combined; the default request is unchanged. */
599
+ async getCloudCotBoard(report: CotFamily, traderClass: CotClass, positions: CotPositions = "futures-only"): Promise<CotBoardPayload> {
600
+ const query = new URLSearchParams({ report, traderClass, ...(positions === "combined" ? { scope: positions } : {}) });
601
+ return this.request<CotBoardPayload>(`/cloud/cot/board?${query}`);
594
602
  }
595
603
 
596
- async getCloudCotContract(code: string, report: CotFamily): Promise<CotContractPayload> {
597
- return this.request<CotContractPayload>(`/cloud/cot/contracts/${encodeURIComponent(code)}?${new URLSearchParams({ report })}`);
604
+ async getCloudCotContract(code: string, report: CotFamily, positions: CotPositions = "futures-only"): Promise<CotContractPayload> {
605
+ const query = new URLSearchParams({ report, ...(positions === "combined" ? { scope: positions } : {}) });
606
+ return this.request<CotContractPayload>(`/cloud/cot/contracts/${encodeURIComponent(code)}?${query}`);
598
607
  }
599
608
 
600
609
  /** Geo layers (the map's layers, entities and series); one prefix-scoped method, like EQS. */
@@ -687,6 +696,8 @@ export class CloudDataApi {
687
696
  }
688
697
  async getCloudPerpsRankings(): Promise<PerpRankingsPayload> { return this.request("/cloud/perps/rankings"); }
689
698
  async getCloudPerpsCompare(baseAsset: string): Promise<PerpBoardPayload> { return this.request(`/cloud/perps/compare?${new URLSearchParams({ baseAsset })}`); }
699
+ async getCloudPerpsLiquidations(baseAsset: string): Promise<PerpLiquidationsPayload> { return this.request(`/cloud/perps/liquidations?${new URLSearchParams({ baseAsset })}`); }
700
+ async getCloudPerpsDepth(baseAsset: string): Promise<PerpDepthPayload> { return this.request(`/cloud/perps/depth?${new URLSearchParams({ baseAsset })}`); }
690
701
  async getCloudPerpsEquity(symbol: string, exchange?: string): Promise<PerpBoardPayload> {
691
702
  const query = exchange === undefined ? "" : `?${new URLSearchParams({ identity: "listing", exchange })}`;
692
703
  return this.request(`/cloud/perps/equity/${encodeURIComponent(symbol)}${query}`);
@@ -897,11 +908,25 @@ export class CloudDataApi {
897
908
  return this.request<CentralBankRatesPayload>("/cloud/econ/central-bank-rates", { signal: AbortSignal.timeout(45_000) });
898
909
  }
899
910
 
911
+ /** A live scan's matches against Gloom Cloud's newest market-wide snapshot for this account's tier. */
912
+ getLiveScan(definition: LiveScanWireDefinition, signal?: AbortSignal) {
913
+ return this.request<LiveScanPayload>(LIVE_SCAN_PATH, {
914
+ method: "POST",
915
+ body: JSON.stringify({ scan: definition }),
916
+ signal: signalWithTimeout(signal, 20_000),
917
+ });
918
+ }
919
+
900
920
  /** Recorded FLOW prints older than the live tape (Pro); the plugin builds `search`. */
901
921
  getScannerFlowHistory(search: string, signal?: AbortSignal) {
902
922
  return this.request<ScannerFlowHistoryPage>(`/market/scanner/flow/history?${search}`, { signal });
903
923
  }
904
924
 
925
+ /** The latest session's recorded FLOW prints summed by side, by time and by strike (Pro); the plugin builds `search`. */
926
+ getScannerFlowSession(search: string, signal?: AbortSignal) {
927
+ return this.request<ScannerFlowSession>(`/market/scanner/flow/session?${search}`, { signal });
928
+ }
929
+
905
930
  getMobileAlertHistory<T>(offset = 0) {
906
931
  return this.request<T>(`/mobile/alerts/history?offset=${offset}`);
907
932
  }
@@ -2,6 +2,27 @@
2
2
  export const KPI_FIELDS = ["kpiArr", "kpiNrrPercent", "kpiRpo", "kpiCrpo", "kpiSubscribers", "kpiDau", "kpiMau", "kpiGmv", "kpiTakeRatePercent", "kpiSameStoreSalesPercent", "kpiStores", "kpiBacklog", "kpiBookToBill", "kpiNimPercent", "kpiCet1Percent", "kpiCombinedRatioPercent", "kpiOccupancyPercent", "kpiLoadFactorPercent", "guideRevenueChangePercent", "guideEpsChangePercent"] as const;
3
3
  /** Payout ratio and dividend growth; listed only when asked (`include=dividends`), and omitted by a server from before them. */
4
4
  export const DIVIDEND_FIELDS = ["payoutRatioPercent", "dividendGrowth1YPercent", "dividendGrowth3YPercent"] as const;
5
+ /**
6
+ * Technical readings of the stored daily bars at the last completed session; listed only when asked
7
+ * (`include=technical`), and omitted by a server from before them.
8
+ */
9
+ export const TECHNICAL_FIELDS = [
10
+ "rsi14",
11
+ "priceVsSma20Percent", "priceVsSma50Percent", "priceVsSma200Percent",
12
+ "macdBullishCrossDays", "macdBearishCrossDays", "goldenCrossDays", "deathCrossDays",
13
+ "newHigh20dDays", "newLow20dDays", "newHigh52wDays", "newLow52wDays",
14
+ "bollingerWidthPercentile",
15
+ ] as const;
16
+ /**
17
+ * IV30, its 52-week percentile and its moves in volatility points, and 20-session realized volatility with its
18
+ * 52-week rank; listed only when asked (`include=option-volatility`), and omitted by a server from before them.
19
+ */
20
+ export const OPTION_VOLATILITY_FIELDS = ["iv30Percent", "ivPercentile", "iv30Change1d", "iv30Change5d", "hv20Percent", "hvRank"] as const;
21
+ /**
22
+ * Shares outstanding, float, short % of float and 13F institutional ownership, each with the day it describes;
23
+ * listed only when asked (`include=ownership`), and omitted by a server from before them.
24
+ */
25
+ export const OWNERSHIP_FIELDS = ["sharesOutstanding", "floatShares", "shortPercentOfFloat", "institutionalOwnershipPercent"] as const;
5
26
  export const NUMERIC_FIELDS = [
6
27
  ...KPI_FIELDS,
7
28
  "price",
@@ -42,6 +63,7 @@ export const NUMERIC_FIELDS = [
42
63
  "fromHigh52WPercent",
43
64
  "beta",
44
65
  "atrPercent",
66
+ ...TECHNICAL_FIELDS,
45
67
  "priceToBook",
46
68
  "evToEbitda",
47
69
  "roePercent",
@@ -49,6 +71,8 @@ export const NUMERIC_FIELDS = [
49
71
  "analystUpsidePercent",
50
72
  "ivRank",
51
73
  "ivToHv",
74
+ ...OPTION_VOLATILITY_FIELDS,
75
+ ...OWNERSHIP_FIELDS,
52
76
  "hiringOpenRoles", "hiringNetAddsWeek", "hiringRemotePercent", "hiringZScore",
53
77
  "appAttentionScore", "appRankVelocity7d", "appRatingDrift7d", "appRatingCountGrowth7d",
54
78
  ] as const;
@@ -6,7 +6,15 @@ interface FundFact<T> {
6
6
  url?: string;
7
7
  }
8
8
 
9
- type FundStructure = "registered" | "trust";
9
+ /**
10
+ * `registered`: a 1940 Act fund (an ETF or UIT). `trust`: an exchange-traded
11
+ * trust or pool outside the 1940 Act. `closed-end`: a registered closed-end
12
+ * fund (ECC, OXLC, PDI), found filing N-CEN, N-CSR, N-PORT or N-2. `bdc`: a
13
+ * business development company (ARCC, MAIN), found filing N-2 or its N-54A
14
+ * election beside its 10-Q and 10-K. Either's shares trade at their own
15
+ * premium or discount to NAV. Servers before them say null.
16
+ */
17
+ export type FundStructure = "registered" | "trust" | "closed-end" | "bdc";
10
18
  type ExpenseRatioKind = "net" | "gross" | "sponsor-fee";
11
19
  /**
12
20
  * A bond fund as its sponsor classes it: `municipal` when its interest is
@@ -67,6 +75,22 @@ export interface FundMetalHoldings {
67
75
  stale: boolean;
68
76
  }
69
77
 
78
+ /**
79
+ * The 1M change in an ETF's shares outstanding (creations less redemptions),
80
+ * from the sponsor's count on `from` to its count on `asOf`. `value` puts a
81
+ * dollar figure on it, each day's change at that day's NAV; null when a day
82
+ * in between had none.
83
+ */
84
+ export interface FundFlows {
85
+ period: "1M";
86
+ shares: number;
87
+ value: number | null;
88
+ from: string;
89
+ asOf: string;
90
+ source: string;
91
+ url?: string;
92
+ }
93
+
70
94
  /**
71
95
  * `not-collected-yet`: a source Gloom reads covers the fund, but it has no
72
96
  * figures yet. `not-published`: no source Gloom reads covers it. Servers
@@ -86,10 +110,23 @@ export interface FundFactsPayload {
86
110
  structure: FundStructure | null;
87
111
  /** `document`: read from the fund's prospectus filed with the SEC on `asOf`, not from its sponsor. */
88
112
  expenseRatio: (FundFact<number> & { kind: ExpenseRatioKind; document?: "prospectus" }) | null;
89
- nav: FundFact<number> | null;
113
+ /**
114
+ * `period`: a `day`'s NAV, or a `month-end`'s (a closed-end fund's monthly
115
+ * estimate, or the NAV per share its filing states), which is its normal
116
+ * cadence rather than a lag. `estimate`: the range the sponsor published,
117
+ * whose midpoint `value` is. Servers before them leave both out.
118
+ */
119
+ nav: (FundFact<number> & { period?: "day" | "month-end"; estimate?: { low: number; high: number } }) | null;
120
+ /** Why a covered fund has no NAV, in one line. Absent when it has one, and from servers before it. */
121
+ navReason?: string;
122
+ /** Dated by its own session: a month end on a weekend is priced at the Friday before it. */
90
123
  closingPrice: FundFact<number> | null;
91
- /** `published` by the sponsor, or `computed` from the closing price against the NAV. */
92
- premiumDiscount: (FundFact<number> & { basis: "published" | "computed" }) | null;
124
+ /**
125
+ * `published` by the sponsor, or `computed` from the closing price against
126
+ * the NAV, dated by the NAV. `estimate`: computed against the midpoint of a
127
+ * NAV estimate, so an estimate too; absent from servers before it.
128
+ */
129
+ premiumDiscount: (FundFact<number> & { basis: "published" | "computed"; estimate?: true }) | null;
93
130
  /**
94
131
  * `period`: a `day`'s figure, or the last `month-end`'s (Vanguard and ARK
95
132
  * ETFs, N-PORT), which is not today's. `document`: the fund's N-PORT report
@@ -105,6 +142,10 @@ export interface FundFactsPayload {
105
142
  bond?: FundBondFacts | null;
106
143
  /** A metal trust's metal in trust; absent for any other fund, until its first read, and from servers before it. */
107
144
  metalHoldings?: FundMetalHoldings | null;
145
+ /** Shares outstanding as the sponsor's file states them, dated. Servers before it leave it out. */
146
+ sharesOutstanding?: FundFact<number> | null;
147
+ /** The 1M change in shares outstanding; null until a month of counts is kept. Servers before it leave it out. */
148
+ flows?: FundFlows | null;
108
149
  /** The newest NAV is older than a few US trading days: every figure is older than it looks. */
109
150
  stale: boolean;
110
151
  fetchedAt: string | null;