@gloom-sh/terminal 0.19.1 → 0.19.3

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 (554) hide show
  1. package/README.md +7 -1
  2. package/package.json +2 -1
  3. package/patches/electrobun@1.18.1.patch +108 -1
  4. package/src/account/upgrade-dialog.tsx +4 -23
  5. package/src/api-client/coalesce.ts +118 -0
  6. package/src/api-client/credit-boards.ts +13 -0
  7. package/src/api-client/crypto-etf-flows.ts +6 -0
  8. package/src/api-client/crypto-markets.ts +40 -0
  9. package/src/api-client/data.ts +201 -14
  10. package/src/api-client/equity-screener.ts +10 -0
  11. package/src/api-client/errors.ts +58 -0
  12. package/src/api-client/gpu.ts +29 -0
  13. package/src/api-client/index.ts +5 -2
  14. package/src/api-client/plan-access.ts +10 -1
  15. package/src/api-client/plan-rules.ts +35 -0
  16. package/src/api-client/research-activity.ts +1 -32
  17. package/src/api-client/types.ts +21 -1
  18. package/src/app/attention-notice.tsx +94 -0
  19. package/src/app/runtime/startup.ts +3 -1
  20. package/src/app.tsx +23 -1
  21. package/src/architecture/core-builtin-allowlist.json +2 -1
  22. package/src/capabilities/chart-series.ts +2 -1
  23. package/src/capabilities/factories.ts +1 -0
  24. package/src/cli/ascii-output.ts +42 -0
  25. package/src/cli/base-converter.ts +10 -2
  26. package/src/cli/command-options.ts +16 -1
  27. package/src/cli/commands/crypto-hints.ts +23 -4
  28. package/src/cli/commands/market.ts +101 -27
  29. package/src/cli/commands/news-search.ts +24 -5
  30. package/src/cli/commands/overview.ts +14 -10
  31. package/src/cli/commands/search.ts +84 -25
  32. package/src/cli/commands/system.ts +22 -30
  33. package/src/cli/commands/ticker.ts +49 -9
  34. package/src/cli/commands/version.ts +33 -0
  35. package/src/cli/context.ts +6 -9
  36. package/src/cli/data-dir.ts +7 -0
  37. package/src/cli/desktop-pane-shot-api-policy.ts +85 -0
  38. package/src/cli/desktop-pane-shot-browser.ts +320 -0
  39. package/src/cli/desktop-pane-shot-routes.ts +26 -1
  40. package/src/cli/desktop-pane-shot.ts +196 -256
  41. package/src/cli/early-command.ts +42 -0
  42. package/src/cli/earnings-calendar.ts +9 -0
  43. package/src/cli/entry.ts +19 -13
  44. package/src/cli/errors.ts +12 -2
  45. package/src/cli/glossary.ts +2 -1
  46. package/src/cli/help.ts +1 -1
  47. package/src/cli/history-export.ts +22 -2
  48. package/src/cli/history-rows.ts +189 -11
  49. package/src/cli/index.ts +18 -1
  50. package/src/cli/known-gaps.ts +51 -5
  51. package/src/cli/listing-arg.ts +63 -10
  52. package/src/cli/options.ts +1 -1
  53. package/src/cli/output-file.ts +60 -13
  54. package/src/cli/pane-functions/catalog.ts +14 -3
  55. package/src/cli/pane-functions/data.ts +1 -1
  56. package/src/cli/pane-functions/dom.ts +45 -0
  57. package/src/cli/pane-functions/freshness.ts +46 -9
  58. package/src/cli/pane-functions/function-help.ts +17 -9
  59. package/src/cli/pane-functions/headless.ts +22 -14
  60. package/src/cli/pane-functions/index.ts +6 -2
  61. package/src/cli/pane-functions/options.ts +6 -2
  62. package/src/cli/pane-functions/resolver.ts +27 -5
  63. package/src/cli/pane-functions/screenshot-assessment.ts +33 -0
  64. package/src/cli/pane-functions/screenshot-bridge.ts +94 -13
  65. package/src/cli/pane-functions/screenshot-http.ts +70 -0
  66. package/src/cli/pane-functions/screenshot-render.ts +19 -5
  67. package/src/cli/quote-answer.ts +49 -6
  68. package/src/cli/registry.ts +41 -13
  69. package/src/cli/result.ts +12 -6
  70. package/src/cli/ticker-resolution.ts +2 -1
  71. package/src/cli/types.ts +2 -0
  72. package/src/components/chart/composite/format.ts +3 -0
  73. package/src/components/chart-table/header.tsx +1 -1
  74. package/src/components/chart-table/layout.ts +28 -11
  75. package/src/components/command-bar/action-runtime.ts +4 -0
  76. package/src/components/command-bar/commands/direct/index.ts +18 -33
  77. package/src/components/command-bar/commands/direct/runtime.ts +5 -0
  78. package/src/components/command-bar/commands/registry.ts +10 -1
  79. package/src/components/command-bar/routes/root/command-items.ts +9 -4
  80. package/src/components/command-bar/routes/root/runtime.ts +51 -6
  81. package/src/components/command-bar/selection-runtime.ts +12 -29
  82. package/src/components/command-bar/surface/index.tsx +9 -3
  83. package/src/components/company-logo.tsx +2 -1
  84. package/src/components/layout/detached-pane-shell.tsx +2 -2
  85. package/src/components/layout/header.tsx +10 -5
  86. package/src/components/layout/market-summary.ts +25 -7
  87. package/src/components/layout/pane/footer/index.tsx +8 -2
  88. package/src/components/layout/pane/footer/model.ts +73 -6
  89. package/src/components/layout/pane/header.tsx +2 -2
  90. package/src/components/layout/pane/status-footer.ts +2 -1
  91. package/src/components/market-board/index.tsx +3 -2
  92. package/src/components/onboarding/desks-step.tsx +12 -4
  93. package/src/components/onboarding/first-run-workspace.ts +81 -4
  94. package/src/components/onboarding/onboarding-frame.tsx +4 -2
  95. package/src/components/onboarding/onboarding-keyboard.ts +8 -5
  96. package/src/components/onboarding/onboarding-wizard.tsx +60 -26
  97. package/src/components/onboarding/portfolio-step/positions-panel.tsx +7 -2
  98. package/src/components/onboarding/run-setup-again.ts +24 -0
  99. package/src/components/onboarding/use-onboarding-progress.ts +33 -15
  100. package/src/components/onboarding/use-onboarding-upgrade.ts +2 -6
  101. package/src/components/onboarding/wizard-model.ts +57 -3
  102. package/src/components/onboarding/wizard-positions.ts +1 -1
  103. package/src/components/ui/delayed-mark.tsx +56 -0
  104. package/src/components/ui/display.tsx +16 -5
  105. package/src/components/ui/external-link.tsx +3 -6
  106. package/src/components/ui/icon.tsx +16 -3
  107. package/src/components/ui/logo-mark.tsx +8 -5
  108. package/src/components/ui/stat-grid.tsx +263 -19
  109. package/src/core/app-services.ts +11 -2
  110. package/src/data/app-persistence.ts +9 -7
  111. package/src/data/config/store/node.ts +11 -5
  112. package/src/data/config/store/normalize.ts +16 -3
  113. package/src/data/plugin-cache.ts +15 -0
  114. package/src/data/plugin-state-store.ts +81 -24
  115. package/src/data/profile-permissions.ts +47 -0
  116. package/src/data/resource-store.ts +165 -90
  117. package/src/data/session-store.ts +31 -8
  118. package/src/data/sqlite/access.ts +324 -0
  119. package/src/data/sqlite/checkpointer.ts +285 -0
  120. package/src/data/sqlite/database.ts +80 -4
  121. package/src/data/sqlite/retry.ts +50 -9
  122. package/src/data/ticker-store.ts +57 -23
  123. package/src/docs/snapshot.json +191 -78
  124. package/src/i18n/es.ts +18 -2
  125. package/src/i18n/ja.ts +18 -2
  126. package/src/i18n/ko.ts +18 -2
  127. package/src/i18n/zh-cn.ts +18 -2
  128. package/src/i18n/zh-tw.ts +18 -2
  129. package/src/layout/desk-keys.ts +4 -1
  130. package/src/layout/desks.ts +38 -5
  131. package/src/layout-marketplace/gallery-desktop.tsx +45 -16
  132. package/src/market-data/batched-reads.ts +16 -0
  133. package/src/market-data/coordinator/auxiliary.ts +4 -2
  134. package/src/market-data/coordinator/index.ts +11 -2
  135. package/src/market-data/futures-board.ts +1 -1
  136. package/src/market-data/futures-contract.ts +3 -1
  137. package/src/market-data/market/index-level.ts +6 -4
  138. package/src/market-data/published-apac-sessions.ts +6 -0
  139. package/src/market-data/realized-volatility.ts +4 -2
  140. package/src/news/aggregator.ts +7 -4
  141. package/src/news/news-model.ts +11 -0
  142. package/src/news/story-id.ts +22 -0
  143. package/src/news/ticker-symbols.ts +17 -1
  144. package/src/notifications/app-notifier.ts +35 -14
  145. package/src/plugins/auto-update-node.ts +10 -6
  146. package/src/plugins/builtin/account-management/form-components.tsx +1 -1
  147. package/src/plugins/builtin/account-management/index.tsx +2 -3
  148. package/src/plugins/builtin/account-management/model.ts +1 -1
  149. package/src/plugins/builtin/alerts/cli-forms.ts +15 -1
  150. package/src/plugins/builtin/alerts/events-pane.tsx +7 -5
  151. package/src/plugins/builtin/alerts/events.ts +10 -2
  152. package/src/plugins/builtin/alerts/index.tsx +5 -5
  153. package/src/plugins/builtin/alerts/research-builder.ts +5 -1
  154. package/src/plugins/builtin/alerts/research-rules.ts +18 -0
  155. package/src/plugins/builtin/alerts/targets.ts +4 -1
  156. package/src/plugins/builtin/attention/headless.ts +1 -1
  157. package/src/plugins/builtin/attention/index.tsx +2 -4
  158. package/src/plugins/builtin/attention/listing.ts +1 -1
  159. package/src/plugins/builtin/attention/series.ts +1 -1
  160. package/src/plugins/builtin/awards/index.tsx +1 -2
  161. package/src/plugins/builtin/backtest/client.ts +1 -0
  162. package/src/plugins/builtin/backtest/index.tsx +1 -2
  163. package/src/plugins/builtin/backtest/rules.ts +3 -1
  164. package/src/plugins/builtin/backtest/window.ts +8 -7
  165. package/src/plugins/builtin/broker-manager/detail.tsx +16 -3
  166. package/src/plugins/builtin/broker-manager/index.tsx +1 -1
  167. package/src/plugins/builtin/buildout/cells.tsx +5 -0
  168. package/src/plugins/builtin/buildout/company/flow.tsx +367 -0
  169. package/src/plugins/builtin/buildout/company/id.ts +2 -0
  170. package/src/plugins/builtin/buildout/company/model.ts +247 -0
  171. package/src/plugins/builtin/buildout/company/pane.tsx +317 -0
  172. package/src/plugins/builtin/buildout/data-runtime.ts +31 -10
  173. package/src/plugins/builtin/buildout/facilities.ts +309 -0
  174. package/src/plugins/builtin/buildout/format.ts +9 -0
  175. package/src/plugins/builtin/buildout/index.tsx +51 -5
  176. package/src/plugins/builtin/buildout/model/index.ts +62 -10
  177. package/src/plugins/builtin/buildout/model/normalizers.ts +5 -0
  178. package/src/plugins/builtin/buildout/model/types.ts +11 -2
  179. package/src/plugins/builtin/buildout/pane/index.tsx +91 -20
  180. package/src/plugins/builtin/buildout/pane/status.tsx +1 -1
  181. package/src/plugins/builtin/buildout/pane/themes.tsx +110 -0
  182. package/src/plugins/builtin/buildout/table-model.ts +26 -2
  183. package/src/plugins/builtin/builtin-plugin-meta.ts +16 -0
  184. package/src/plugins/builtin/cds/headless.ts +10 -2
  185. package/src/plugins/builtin/cds/model.ts +7 -3
  186. package/src/plugins/builtin/central-bank-rates/index.tsx +1 -2
  187. package/src/plugins/builtin/central-bank-rates/pane.tsx +2 -1
  188. package/src/plugins/builtin/central-bank-rates/series.ts +2 -3
  189. package/src/plugins/builtin/changelog/index.tsx +3 -2
  190. package/src/plugins/builtin/chart-composer/cli-options.ts +16 -0
  191. package/src/plugins/builtin/chart-composer/headless-schema.ts +10 -0
  192. package/src/plugins/builtin/chart-composer/headless.ts +88 -21
  193. package/src/plugins/builtin/chart-composer/index.tsx +2 -3
  194. package/src/plugins/builtin/chart-composer/pane.tsx +30 -2
  195. package/src/plugins/builtin/chart-composer/series-expression.ts +3 -2
  196. package/src/plugins/builtin/chart-composer/session-range.ts +5 -2
  197. package/src/plugins/builtin/chart-composer/studies.ts +1 -1
  198. package/src/plugins/builtin/chat/controller/index.ts +1 -1
  199. package/src/plugins/builtin/chat/controller/messages.ts +15 -4
  200. package/src/plugins/builtin/chat/ghost-user.ts +8 -0
  201. package/src/plugins/builtin/chat/index.tsx +5 -5
  202. package/src/plugins/builtin/clinical-trials/index.tsx +1 -2
  203. package/src/plugins/builtin/cloud/company-picker.tsx +1 -1
  204. package/src/plugins/builtin/cloud/index.tsx +1 -2
  205. package/src/plugins/builtin/cloud/plugin.tsx +6 -4
  206. package/src/plugins/builtin/cloud/team/module.tsx +1 -1
  207. package/src/plugins/builtin/cloud/thesis/module.tsx +1 -1
  208. package/src/plugins/builtin/cloud/trial-offer-status-widget.tsx +24 -1
  209. package/src/plugins/builtin/cloud/upgrade-status-widget.tsx +39 -15
  210. package/src/plugins/builtin/comment-letters/index.tsx +1 -2
  211. package/src/plugins/builtin/commodity-balances/client.ts +4 -1
  212. package/src/plugins/builtin/commodity-balances/index.tsx +3 -3
  213. package/src/plugins/builtin/commodity-balances/pane.tsx +2 -2
  214. package/src/plugins/builtin/congress-trades/aggregates.ts +13 -2
  215. package/src/plugins/builtin/congress-trades/detail.tsx +20 -4
  216. package/src/plugins/builtin/congress-trades/headless.ts +2 -0
  217. package/src/plugins/builtin/congress-trades/model.ts +92 -64
  218. package/src/plugins/builtin/congress-trades/table.tsx +14 -2
  219. package/src/plugins/builtin/connections/index.ts +2 -3
  220. package/src/plugins/builtin/cot/client.ts +28 -2
  221. package/src/plugins/builtin/cot/headless.ts +4 -1
  222. package/src/plugins/builtin/cot/index.tsx +5 -4
  223. package/src/plugins/builtin/cot/model.ts +58 -7
  224. package/src/plugins/builtin/cot/pane.tsx +6 -2
  225. package/src/plugins/builtin/cpi/client.ts +6 -5
  226. package/src/plugins/builtin/cpi/index.tsx +1 -2
  227. package/src/plugins/builtin/credit-boards/cdx-pane.tsx +2 -1
  228. package/src/plugins/builtin/credit-boards/client.ts +7 -2
  229. package/src/plugins/builtin/credit-boards/headless.ts +25 -12
  230. package/src/plugins/builtin/credit-boards/model.ts +29 -0
  231. package/src/plugins/builtin/credit-boards/series.ts +3 -4
  232. package/src/plugins/builtin/credit-boards/sovr-pane.tsx +9 -4
  233. package/src/plugins/builtin/credit-conditions/client.ts +22 -14
  234. package/src/plugins/builtin/crypto-board/bitcoin-network.ts +143 -0
  235. package/src/plugins/builtin/crypto-board/client.ts +5 -5
  236. package/src/plugins/builtin/crypto-board/headless.ts +4 -3
  237. package/src/plugins/builtin/crypto-board/index.tsx +4 -2
  238. package/src/plugins/builtin/crypto-board/series.ts +6 -4
  239. package/src/plugins/builtin/crypto-etf-flows/client.ts +9 -2
  240. package/src/plugins/builtin/crypto-etf-flows/headless.ts +61 -6
  241. package/src/plugins/builtin/crypto-etf-flows/index.tsx +1 -2
  242. package/src/plugins/builtin/crypto-etf-flows/model.ts +14 -1
  243. package/src/plugins/builtin/crypto-etf-flows/pane.tsx +8 -5
  244. package/src/plugins/builtin/debt-maturities/headless.ts +4 -3
  245. package/src/plugins/builtin/debt-maturities/model.ts +17 -1
  246. package/src/plugins/builtin/debt-maturities/pane.tsx +18 -4
  247. package/src/plugins/builtin/debt-maturities/series.ts +3 -3
  248. package/src/plugins/builtin/debug/index.tsx +1 -1
  249. package/src/plugins/builtin/dividend-yield/client.ts +32 -2
  250. package/src/plugins/builtin/dividend-yield/headless.ts +58 -33
  251. package/src/plugins/builtin/dividend-yield/index.tsx +37 -2
  252. package/src/plugins/builtin/dividend-yield/pane.tsx +32 -13
  253. package/src/plugins/builtin/dividend-yield/ranking-reads.ts +73 -0
  254. package/src/plugins/builtin/dividend-yield/ranking-view.tsx +163 -0
  255. package/src/plugins/builtin/dividend-yield/ranking.ts +1 -1
  256. package/src/plugins/builtin/dividend-yield/view.ts +21 -0
  257. package/src/plugins/builtin/docs/index.tsx +2 -3
  258. package/src/plugins/builtin/doe/client.ts +6 -5
  259. package/src/plugins/builtin/doe/headless.ts +16 -3
  260. package/src/plugins/builtin/doe/index.tsx +5 -4
  261. package/src/plugins/builtin/doe/prices.ts +2 -3
  262. package/src/plugins/builtin/doe/series.ts +4 -4
  263. package/src/plugins/builtin/earnings/board.tsx +2 -1
  264. package/src/plugins/builtin/earnings/history.tsx +2 -1
  265. package/src/plugins/builtin/earnings-calls/calendar.tsx +10 -2
  266. package/src/plugins/builtin/earnings-calls/data.ts +19 -11
  267. package/src/plugins/builtin/earnings-calls/pane.tsx +27 -14
  268. package/src/plugins/builtin/earnings-ripple/client.ts +32 -7
  269. package/src/plugins/builtin/earnings-ripple/index.tsx +1 -2
  270. package/src/plugins/builtin/econ/calendar-model.ts +29 -6
  271. package/src/plugins/builtin/econ/detail-view.tsx +16 -2
  272. package/src/plugins/builtin/econ-statistics/index.tsx +1 -2
  273. package/src/plugins/builtin/equity-screener/client.ts +1 -1
  274. package/src/plugins/builtin/equity-screener/headless.ts +1 -0
  275. package/src/plugins/builtin/equity-screener/ideas.ts +30 -1
  276. package/src/plugins/builtin/equity-screener/index.tsx +1 -2
  277. package/src/plugins/builtin/equity-screener/model.ts +28 -4
  278. package/src/plugins/builtin/equity-screener/pane.tsx +5 -0
  279. package/src/plugins/builtin/equity-screener/screen-check.ts +23 -1
  280. package/src/plugins/builtin/estimate-revisions/index.tsx +1 -2
  281. package/src/plugins/builtin/executives/data.ts +6 -1
  282. package/src/plugins/builtin/executives/pane.tsx +9 -21
  283. package/src/plugins/builtin/exposure/holdings.ts +35 -13
  284. package/src/plugins/builtin/exposure/index.tsx +1 -2
  285. package/src/plugins/builtin/fear-greed/cache.ts +4 -0
  286. package/src/plugins/builtin/fear-greed/cli.ts +44 -0
  287. package/src/plugins/builtin/fear-greed/index.tsx +5 -53
  288. package/src/plugins/builtin/fear-greed/pane.tsx +2 -1
  289. package/src/plugins/builtin/fear-greed/series.ts +6 -4
  290. package/src/plugins/builtin/fixed-income/index.tsx +1 -2
  291. package/src/plugins/builtin/futures/board-reads.ts +25 -0
  292. package/src/plugins/builtin/futures/coalesced-bump.ts +44 -0
  293. package/src/plugins/builtin/futures/index.tsx +15 -0
  294. package/src/plugins/builtin/futures/model.ts +14 -0
  295. package/src/plugins/builtin/futures/use-board-terms.ts +22 -15
  296. package/src/plugins/builtin/futures/use-front-returns.ts +20 -14
  297. package/src/plugins/builtin/futures-curve/headless.ts +6 -1
  298. package/src/plugins/builtin/futures-curve/index.tsx +1 -2
  299. package/src/plugins/builtin/fx-matrix/index.tsx +2 -2
  300. package/src/plugins/builtin/gpu/board.tsx +51 -12
  301. package/src/plugins/builtin/gpu/client.ts +19 -3
  302. package/src/plugins/builtin/gpu/equities.tsx +5 -2
  303. package/src/plugins/builtin/gpu/headless.ts +14 -2
  304. package/src/plugins/builtin/gpu/index.tsx +1 -2
  305. package/src/plugins/builtin/gpu/model.ts +20 -2
  306. package/src/plugins/builtin/gpu/pane.tsx +1 -1
  307. package/src/plugins/builtin/gpu/series.ts +2 -3
  308. package/src/plugins/builtin/help/index.tsx +1 -1
  309. package/src/plugins/builtin/holders/beneficial-view.tsx +1 -2
  310. package/src/plugins/builtin/holders/index-holders.ts +24 -12
  311. package/src/plugins/builtin/holders/index.tsx +2 -3
  312. package/src/plugins/builtin/ipo-calendar/index.tsx +1 -2
  313. package/src/plugins/builtin/iv-history/index.tsx +1 -2
  314. package/src/plugins/builtin/jodi/client.ts +4 -1
  315. package/src/plugins/builtin/jodi/index.tsx +1 -2
  316. package/src/plugins/builtin/kelly-sizer/index.tsx +1 -2
  317. package/src/plugins/builtin/layout-manager/index.tsx +9 -8
  318. package/src/plugins/builtin/macro-day/pane.tsx +4 -2
  319. package/src/plugins/builtin/market-halts/index.tsx +1 -2
  320. package/src/plugins/builtin/market-heatmap/index.tsx +11 -2
  321. package/src/plugins/builtin/market-movers/client.ts +1 -0
  322. package/src/plugins/builtin/market-movers/index.tsx +16 -5
  323. package/src/plugins/builtin/market-movers/screener.ts +23 -6
  324. package/src/plugins/builtin/market-movers/session-body.tsx +6 -2
  325. package/src/plugins/builtin/market-valuation/index.tsx +1 -2
  326. package/src/plugins/builtin/members/index.tsx +1 -2
  327. package/src/plugins/builtin/money-markets/index.tsx +1 -2
  328. package/src/plugins/builtin/money-markets/pane.tsx +2 -1
  329. package/src/plugins/builtin/money-markets/series.ts +3 -5
  330. package/src/plugins/builtin/news/headless.ts +7 -0
  331. package/src/plugins/builtin/news/wire/index.tsx +1 -1
  332. package/src/plugins/builtin/news/wire/news/pop-out.tsx +9 -3
  333. package/src/plugins/builtin/notes/index.tsx +3 -6
  334. package/src/plugins/builtin/openfda/index.tsx +1 -2
  335. package/src/plugins/builtin/options/view.tsx +6 -5
  336. package/src/plugins/builtin/options-calculator/index.tsx +1 -2
  337. package/src/plugins/builtin/options-positioning/index.tsx +1 -2
  338. package/src/plugins/builtin/options-scenario/index.tsx +2 -4
  339. package/src/plugins/builtin/perps/index.tsx +1 -2
  340. package/src/plugins/builtin/plugin-marketplace/index.tsx +2 -3
  341. package/src/plugins/builtin/plugin-marketplace/pane.tsx +2 -1
  342. package/src/plugins/builtin/plugin-module.ts +16 -2
  343. package/src/plugins/builtin/portfolio-list/cli/render.ts +53 -3
  344. package/src/plugins/builtin/portfolio-list/index.tsx +1 -2
  345. package/src/plugins/builtin/portfolio-list/pane/index.tsx +11 -0
  346. package/src/plugins/builtin/portfolio-list/quick-add/index.tsx +2 -2
  347. package/src/plugins/builtin/power/gas-client.ts +2 -1
  348. package/src/plugins/builtin/power/index.tsx +1 -2
  349. package/src/plugins/builtin/power/prices-client.ts +3 -2
  350. package/src/plugins/builtin/rate-path/index.tsx +1 -2
  351. package/src/plugins/builtin/realized-vol/headless.ts +2 -0
  352. package/src/plugins/builtin/realized-vol/index.tsx +1 -2
  353. package/src/plugins/builtin/realized-vol/model.ts +16 -2
  354. package/src/plugins/builtin/realized-vol/pane.tsx +3 -3
  355. package/src/plugins/builtin/relative-rotation/index.tsx +1 -2
  356. package/src/plugins/builtin/research/analyst-headless.ts +33 -6
  357. package/src/plugins/builtin/research/analyst-model.ts +37 -2
  358. package/src/plugins/builtin/research/analyst-pane.tsx +25 -5
  359. package/src/plugins/builtin/research/index.tsx +5 -8
  360. package/src/plugins/builtin/research-search/index.tsx +1 -2
  361. package/src/plugins/builtin/revenue-breakdown/headless.ts +22 -8
  362. package/src/plugins/builtin/revenue-breakdown/model.ts +23 -0
  363. package/src/plugins/builtin/reverse-dcf/pane.tsx +4 -2
  364. package/src/plugins/builtin/risk-factors/data.ts +8 -4
  365. package/src/plugins/builtin/risk-factors/index.tsx +3 -1
  366. package/src/plugins/builtin/risk-factors/pane.tsx +5 -8
  367. package/src/plugins/builtin/roadmap/index.tsx +2 -3
  368. package/src/plugins/builtin/roadmap/pane.tsx +49 -2
  369. package/src/plugins/builtin/scanner/hilo-model.ts +18 -1
  370. package/src/plugins/builtin/scanner/hilo-pane.tsx +12 -2
  371. package/src/plugins/builtin/scanner/live-pane.tsx +7 -4
  372. package/src/plugins/builtin/scanner/lock-note.ts +26 -3
  373. package/src/plugins/builtin/sec/filing-content.ts +38 -6
  374. package/src/plugins/builtin/sec/headless.ts +5 -1
  375. package/src/plugins/builtin/sec/index.tsx +4 -2
  376. package/src/plugins/builtin/sec/model.ts +2 -0
  377. package/src/plugins/builtin/sectors/index.tsx +11 -5
  378. package/src/plugins/builtin/series-inventory.ts +2 -0
  379. package/src/plugins/builtin/shared/cloud-resource.ts +73 -8
  380. package/src/plugins/builtin/shared/cloud-upgrade.ts +24 -1
  381. package/src/plugins/builtin/shared/forming-bars.ts +29 -0
  382. package/src/plugins/builtin/shared/fred-points.ts +6 -1
  383. package/src/plugins/builtin/shared/fx-rate-freshness.ts +17 -0
  384. package/src/plugins/builtin/shared/pro-lock-note.ts +23 -8
  385. package/src/plugins/builtin/shared/series-detail-chart.tsx +4 -2
  386. package/src/plugins/builtin/shared/series-warning.ts +13 -4
  387. package/src/plugins/builtin/shared/use-quote-board.ts +5 -0
  388. package/src/plugins/builtin/short-interest/publications-pane.tsx +2 -1
  389. package/src/plugins/builtin/short-volume/pane.tsx +2 -1
  390. package/src/plugins/builtin/short-volume/series.ts +2 -3
  391. package/src/plugins/builtin/social-mentions/client.ts +15 -10
  392. package/src/plugins/builtin/social-mentions/index.tsx +1 -2
  393. package/src/plugins/builtin/social-mentions/pane.tsx +2 -1
  394. package/src/plugins/builtin/social-mentions/series.ts +2 -3
  395. package/src/plugins/builtin/supply-chain/client.ts +22 -1
  396. package/src/plugins/builtin/supply-chain/graph-client.ts +22 -1
  397. package/src/plugins/builtin/supply-chain/index.tsx +1 -2
  398. package/src/plugins/builtin/thirteenf/api.ts +127 -29
  399. package/src/plugins/builtin/thirteenf/data.ts +165 -35
  400. package/src/plugins/builtin/thirteenf/index.tsx +2 -4
  401. package/src/plugins/builtin/thirteenf/model.ts +2 -0
  402. package/src/plugins/builtin/thirteenf/overlap-pane.tsx +5 -1
  403. package/src/plugins/builtin/thirteenf/pane.tsx +41 -16
  404. package/src/plugins/builtin/thirteenf/types.ts +14 -0
  405. package/src/plugins/builtin/ticker-detail/data-panes/historical-prices.tsx +22 -6
  406. package/src/plugins/builtin/ticker-detail/data-panes/returns-history.ts +81 -11
  407. package/src/plugins/builtin/ticker-detail/financials/model.ts +35 -2
  408. package/src/plugins/builtin/ticker-detail/financials/ratios.ts +53 -18
  409. package/src/plugins/builtin/ticker-detail/headless.ts +70 -11
  410. package/src/plugins/builtin/ticker-detail/index.tsx +5 -10
  411. package/src/plugins/builtin/ticker-detail/overview-tab.tsx +16 -6
  412. package/src/plugins/builtin/time-sales/index.tsx +1 -2
  413. package/src/plugins/builtin/time-sales/pane.tsx +3 -1
  414. package/src/plugins/builtin/trace-bonds/headless.ts +11 -2
  415. package/src/plugins/builtin/trace-bonds/model.ts +44 -10
  416. package/src/plugins/builtin/trace-bonds/pane.tsx +12 -7
  417. package/src/plugins/builtin/treasury-auctions/cache.ts +20 -8
  418. package/src/plugins/builtin/treasury-auctions/client.ts +3 -3
  419. package/src/plugins/builtin/treasury-auctions/headless.ts +3 -1
  420. package/src/plugins/builtin/treasury-auctions/pane.tsx +10 -4
  421. package/src/plugins/builtin/vol-surface/client.ts +18 -3
  422. package/src/plugins/builtin/vol-surface/index.tsx +1 -2
  423. package/src/plugins/builtin/volatility/client.ts +43 -16
  424. package/src/plugins/builtin/volatility/headless.ts +5 -2
  425. package/src/plugins/builtin/volatility/index.tsx +1 -2
  426. package/src/plugins/builtin/volatility/model.ts +17 -6
  427. package/src/plugins/builtin/volatility/pane.tsx +6 -2
  428. package/src/plugins/builtin/volatility/series.ts +2 -1
  429. package/src/plugins/builtin/world-indices/footer.ts +6 -1
  430. package/src/plugins/builtin/world-venue-map/client.ts +10 -1
  431. package/src/plugins/builtin/world-venue-map/index.ts +6 -2
  432. package/src/plugins/builtin/world-venue-map/layered-pane.tsx +48 -7
  433. package/src/plugins/builtin/world-venue-map/layers.ts +17 -0
  434. package/src/plugins/builtin/world-venue-map/local-layers.ts +141 -0
  435. package/src/plugins/builtin/world-venue-map/map-symbols.ts +18 -0
  436. package/src/plugins/builtin/world-venue-map/map.tsx +4 -2
  437. package/src/plugins/builtin/world-venue-map/scope.ts +63 -0
  438. package/src/plugins/builtin/yield-curve/client.ts +4 -6
  439. package/src/plugins/builtin/yield-curve/curves.ts +16 -2
  440. package/src/plugins/builtin/yield-curve/headless.ts +3 -3
  441. package/src/plugins/bundle.ts +52 -2
  442. package/src/plugins/catalog-browser.ts +2 -2
  443. package/src/plugins/catalog-cli.ts +20 -0
  444. package/src/plugins/host-link.ts +13 -1
  445. package/src/plugins/installer.ts +64 -42
  446. package/src/plugins/loader.ts +43 -11
  447. package/src/plugins/peer-imports.ts +201 -0
  448. package/src/plugins/peer-retry.ts +26 -29
  449. package/src/plugins/plugin-process.ts +128 -0
  450. package/src/plugins/redirection-guard.ts +45 -0
  451. package/src/remote/endpoint.ts +16 -3
  452. package/src/renderers/browser/main.tsx +3 -2
  453. package/src/renderers/cloudflare/http-proxy.ts +7 -123
  454. package/src/renderers/dom/desktop/icons.tsx +5 -2
  455. package/src/renderers/dom/host/image-surface.tsx +46 -21
  456. package/src/renderers/dom/styles.css +7 -0
  457. package/src/renderers/dom/toast-host.tsx +2 -0
  458. package/src/renderers/electrobun/bun/desktop/backend.ts +7 -1
  459. package/src/renderers/electrobun/bun/desktop/detached-windows.ts +23 -1
  460. package/src/renderers/electrobun/bun/desktop/initialization.ts +12 -3
  461. package/src/renderers/electrobun/bun/desktop/rpc-timing.ts +88 -0
  462. package/src/renderers/electrobun/bun/desktop/update.ts +20 -4
  463. package/src/renderers/electrobun/bun/desktop/view-ids.ts +8 -4
  464. package/src/renderers/electrobun/bun/external-plugins.ts +4 -0
  465. package/src/renderers/electrobun/bun/window/attention.ts +54 -0
  466. package/src/renderers/electrobun/bun/window/create.ts +6 -2
  467. package/src/renderers/electrobun/bun/window/native-timing.ts +48 -0
  468. package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +82 -4
  469. package/src/renderers/electrobun/view/cli-pane-shot-frame.tsx +13 -5
  470. package/src/renderers/electrobun/view/desktop/window/snapshot.ts +3 -0
  471. package/src/renderers/electrobun/view/main.tsx +7 -2
  472. package/src/renderers/electrobun/view/remote/asset-data-client.ts +1 -0
  473. package/src/renderers/electrobun/view/ui-host.tsx +9 -2
  474. package/src/renderers/opentui/browser-open.ts +10 -4
  475. package/src/renderers/opentui/image/surface.tsx +1 -1
  476. package/src/renderers/opentui/start.tsx +12 -6
  477. package/src/renderers/opentui/toast-host.tsx +2 -1
  478. package/src/series/registry.ts +18 -0
  479. package/src/series/resolve.ts +2 -1
  480. package/src/series/standalone.ts +10 -1
  481. package/src/series/types.ts +12 -0
  482. package/src/series/validate.ts +11 -2
  483. package/src/sources/gloomberb-cloud/fred-series.ts +5 -3
  484. package/src/sources/gloomberb-cloud/index.ts +28 -5
  485. package/src/sources/gloomberb-cloud/news.ts +24 -3
  486. package/src/sources/gloomberb-cloud/normalizers.ts +17 -2
  487. package/src/sources/provider-errors.ts +26 -3
  488. package/src/sources/provider-router/history.ts +5 -0
  489. package/src/sources/provider-router/index.ts +13 -0
  490. package/src/sync/core-contributors.ts +32 -0
  491. package/src/telemetry/attention-counts.ts +64 -6
  492. package/src/telemetry/attention-setting.ts +33 -0
  493. package/src/telemetry/crash-reports-node.ts +3 -1
  494. package/src/telemetry/stall-clocks.ts +93 -0
  495. package/src/telemetry/stall-reports-node.ts +25 -9
  496. package/src/telemetry/stall-reports.ts +218 -13
  497. package/src/test-support/outage.ts +8 -0
  498. package/src/test-support/preload.ts +9 -0
  499. package/src/tickers/company-name-listing.ts +59 -29
  500. package/src/tickers/company-name.ts +84 -1
  501. package/src/tickers/listing-fate.ts +14 -3
  502. package/src/tickers/saved-instrument.ts +17 -0
  503. package/src/tickers/search/home-listing.ts +104 -8
  504. package/src/tickers/search/index.ts +5 -2
  505. package/src/tickers/search/types.ts +6 -1
  506. package/src/time-series/bar-aggregation.ts +7 -1
  507. package/src/time-series/base-series.ts +3 -3
  508. package/src/time-series/chart-bounds.ts +1 -1
  509. package/src/time-series/chart-data.ts +5 -2
  510. package/src/time-series/chart-seed.ts +1 -1
  511. package/src/time-series/coin-session-close.ts +211 -0
  512. package/src/time-series/live-bars.ts +13 -2
  513. package/src/time-series/live-quotes.ts +1 -1
  514. package/src/time-series/market.ts +5 -3
  515. package/src/time-series/official-close.ts +159 -0
  516. package/src/time-series/price-comparison.ts +75 -8
  517. package/src/time-series/resolve.ts +32 -4
  518. package/src/time-series/series-presentation.ts +1 -1
  519. package/src/time-series/studies/formula.ts +205 -0
  520. package/src/time-series/studies/indicators.ts +299 -0
  521. package/src/time-series/studies/leverage.ts +75 -0
  522. package/src/time-series/studies/pair.ts +138 -0
  523. package/src/time-series/studies/resolve.ts +333 -0
  524. package/src/time-series/studies/shared.ts +141 -0
  525. package/src/time-series/studies/units.ts +243 -0
  526. package/src/time-series/studies/vwap.ts +274 -0
  527. package/src/time-series/types.ts +7 -0
  528. package/src/types/config.ts +18 -2
  529. package/src/types/data-provider.ts +23 -0
  530. package/src/types/financials.ts +40 -3
  531. package/src/types/headless.ts +42 -3
  532. package/src/types/plugin.ts +32 -3
  533. package/src/ui/host.tsx +17 -1
  534. package/src/ui/toast.tsx +26 -1
  535. package/src/utils/ascii-text.ts +140 -0
  536. package/src/utils/cli-output.ts +91 -18
  537. package/src/utils/concurrency.ts +24 -0
  538. package/src/utils/exchanges.ts +6 -0
  539. package/src/utils/external-url.ts +20 -7
  540. package/src/utils/financial-statements.ts +73 -16
  541. package/src/utils/fundamentals.ts +17 -5
  542. package/src/utils/futures-generic.ts +4 -4
  543. package/src/utils/http-proxy-upstream.ts +124 -0
  544. package/src/utils/lease-liabilities.ts +54 -0
  545. package/src/utils/main-thread-stall.ts +122 -5
  546. package/src/utils/perf-marks.ts +58 -12
  547. package/src/utils/price-history-integrity.ts +47 -1
  548. package/src/utils/private-files.ts +141 -0
  549. package/src/utils/public-address.ts +99 -0
  550. package/src/account/upgrade-personalization.ts +0 -57
  551. package/src/account/upgrade-tickers.ts +0 -124
  552. package/src/api-client/upgrade-experiment.ts +0 -91
  553. package/src/plugins/builtin/cloud/browser.tsx +0 -3
  554. package/src/time-series/studies.ts +0 -1628
package/README.md CHANGED
@@ -45,7 +45,13 @@ For the terminal on **macOS or Linux**:
45
45
  curl -fsSL gloom.sh/install | bash
46
46
  ```
47
47
 
48
- The script downloads the prebuilt release from GitHub and checks its SHA-256 against the digest GitHub lists. Apple Silicon Macs get the desktop app and the `gloom` command; Linux and Intel Macs get the standalone binary. It asks for `sudo` only if the destination isn't writable. Prefer to download it yourself? See the [installation guide](docs/installation.md).
48
+ For the terminal on **Windows**, in PowerShell:
49
+
50
+ ```powershell
51
+ irm https://gloom.sh/install.ps1 | iex
52
+ ```
53
+
54
+ The script downloads the prebuilt release from GitHub and checks its SHA-256 against the checksum file the release publishes beside it, installing nothing if they differ. Apple Silicon Macs get the desktop app and the `gloom` command; Linux and Intel Macs get the standalone binary. The PowerShell line does the same on Windows: it puts the standalone `gloom.exe` in `%USERPROFILE%\.local\bin` and adds that folder to your PATH. It asks for `sudo` only if the destination isn't writable. Prefer to download it yourself? See the [installation guide](docs/installation.md).
49
55
 
50
56
  With [Bun](https://bun.sh), on any supported OS:
51
57
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gloom-sh/terminal",
3
- "version": "0.19.1",
3
+ "version": "0.19.3",
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",
@@ -91,6 +91,7 @@
91
91
  "check:pane-layout": "bun run scripts/pane-chrome/layout-sweep.ts",
92
92
  "check:ui-tokens": "bun run scripts/pane-chrome/ui-tokens.ts",
93
93
  "ui:benchmark": "bun run scripts/pane-chrome/ui-benchmark.ts",
94
+ "ui:badge-ink": "bun run scripts/pane-chrome/badge-ink.ts",
94
95
  "audit:ui": "bun run scripts/pane-chrome/ui-audit.ts",
95
96
  "check:call-player": "bun run scripts/pane-chrome/call-player.ts",
96
97
  "check:chart-axis-zoom": "bun run scripts/pane-chrome/chart-axis-zoom.ts",
@@ -495,7 +495,7 @@ index a7822d85c187c1edf361f2e65757057aad9da7b0..533d431c6cc2097951f421cb1fbe3142
495
495
 
496
496
  async function generateKeyFromBytes(rawKey: Uint8Array): Promise<CryptoKey> {
497
497
  diff --git a/dist/api/bun/proc/native.ts b/dist/api/bun/proc/native.ts
498
- index f0f6c2532ba2eb467ec1d452a25c835b6db72661..ae77cf58d32392ad4cc8e2103ac7ed27baae8bea 100644
498
+ index f0f6c2532ba2eb467ec1d452a25c835b6db72661..3b9cc732f8d71da17e71c019f0930e74d0fb578d 100644
499
499
  --- a/dist/api/bun/proc/native.ts
500
500
  +++ b/dist/api/bun/proc/native.ts
501
501
  @@ -829,6 +829,7 @@ const _ffiImpl = {
@@ -524,3 +524,110 @@ index f0f6c2532ba2eb467ec1d452a25c835b6db72661..ae77cf58d32392ad4cc8e2103ac7ed27
524
524
  if (!hidden) {
525
525
  native_.symbols.showWindow(windowPtr, activate);
526
526
  }
527
+ @@ -1915,6 +1920,14 @@ process.on("SIGTERM", () => {
528
+ // }
529
+ // );
530
+
531
+ +// A JSCallback's cstring argument arrives as the pointer under Bun 1.3 and as
532
+ +// a string (null for NULL) under Bun 1.4, which Windows builds ship.
533
+ +function callbackString(value: unknown): string {
534
+ + if (typeof value === "string") return value;
535
+ + if (value === null || value === undefined) return "";
536
+ + return new CString(value as Pointer).toString();
537
+ +}
538
+ +
539
+ const windowCloseCallback = new JSCallback(
540
+ (id) => {
541
+ const handler = electrobunEventEmitter.events.window.close;
542
+ @@ -2036,7 +2049,7 @@ const windowKeyCallback = new JSCallback(
543
+
544
+ const getMimeType = new JSCallback(
545
+ (filePath) => {
546
+ - const _filePath = new CString(filePath).toString();
547
+ + const _filePath = callbackString(filePath);
548
+ const mimeType = Bun.file(_filePath).type; // || "application/octet-stream";
549
+
550
+ // For this usecase we generally don't want the charset included in the mimetype
551
+ @@ -2074,7 +2087,7 @@ const globalShortcutHandlers = new Map<string, () => void>();
552
+ if (native) {
553
+ const urlOpenCallback = new JSCallback(
554
+ (urlPtr) => {
555
+ - const url = new CString(urlPtr).toString();
556
+ + const url = callbackString(urlPtr);
557
+ const handler = electrobunEventEmitter.events.app.openUrl;
558
+ const event = handler({ url });
559
+ electrobunEventEmitter.emitEvent(event);
560
+ @@ -2111,7 +2124,7 @@ if (native) {
561
+
562
+ const globalShortcutCallback = new JSCallback(
563
+ (acceleratorPtr) => {
564
+ - const accelerator = new CString(acceleratorPtr).toString();
565
+ + const accelerator = callbackString(acceleratorPtr);
566
+ const handler = globalShortcutHandlers.get(accelerator);
567
+ if (handler) handler();
568
+ },
569
+ @@ -2505,8 +2518,8 @@ const webviewEventJSCallback = new JSCallback(
570
+
571
+ try {
572
+ // Convert cstring pointers to actual strings
573
+ - eventName = new CString(_eventName).toString();
574
+ - detail = new CString(_detail).toString();
575
+ + eventName = callbackString(_eventName);
576
+ + detail = callbackString(_detail);
577
+ } catch (err) {
578
+ console.error("[webviewEventJSCallback] Error converting strings:", err);
579
+ console.error("[webviewEventJSCallback] Raw values:", {
580
+ @@ -2528,7 +2541,7 @@ const webviewEventJSCallback = new JSCallback(
581
+ const bunBridgePostmessageHandler = new JSCallback(
582
+ (id, msg) => {
583
+ try {
584
+ - const msgStr = new CString(msg);
585
+ + const msgStr = callbackString(msg);
586
+
587
+ if (!msgStr.length) {
588
+ return;
589
+ @@ -2564,7 +2577,7 @@ const bunBridgePostmessageHandler = new JSCallback(
590
+ const eventBridgeHandler = new JSCallback(
591
+ (_id: number, msg: number) => {
592
+ try {
593
+ - const message = new CString(msg as unknown as Pointer);
594
+ + const message = callbackString(msg);
595
+ const rawMessage = message.toString().trim();
596
+ if (!rawMessage || (rawMessage[0] !== "{" && rawMessage[0] !== "[")) {
597
+ return;
598
+ @@ -2593,7 +2606,7 @@ const eventBridgeHandler = new JSCallback(
599
+ const internalBridgeHandler = new JSCallback(
600
+ (_id: number, msg: number) => {
601
+ try {
602
+ - const batchMessage = new CString(msg as unknown as Pointer);
603
+ + const batchMessage = callbackString(msg);
604
+ const jsonBatch = JSON.parse(batchMessage.toString());
605
+
606
+ if (jsonBatch.id === "webviewEvent") {
607
+ @@ -2664,7 +2677,7 @@ const trayItemHandler = new JSCallback(
608
+ (id, action) => {
609
+ // Note: Some invisible character that doesn't appear in .length
610
+ // is causing issues
611
+ - const actionString = (new CString(action).toString() || "").trim();
612
+ + const actionString = (callbackString(action) || "").trim();
613
+
614
+ // Use shared deserialization method
615
+ const { action: actualAction, data } = deserializeMenuAction(actionString);
616
+ @@ -2688,7 +2701,7 @@ const trayItemHandler = new JSCallback(
617
+
618
+ const applicationMenuHandler = new JSCallback(
619
+ (id, action) => {
620
+ - const actionString = new CString(action).toString();
621
+ + const actionString = callbackString(action);
622
+
623
+ // Use shared deserialization method
624
+ const { action: actualAction, data } = deserializeMenuAction(actionString);
625
+ @@ -2711,7 +2724,7 @@ const applicationMenuHandler = new JSCallback(
626
+
627
+ const contextMenuHandler = new JSCallback(
628
+ (_id, action) => {
629
+ - const actionString = new CString(action).toString();
630
+ + const actionString = callbackString(action);
631
+
632
+ // Use shared deserialization method
633
+ const { action: actualAction, data } = deserializeMenuAction(actionString);
@@ -23,8 +23,6 @@ import {
23
23
  monthsFreeYearly,
24
24
  trialDaysOf,
25
25
  } from "./billing";
26
- import { useUpgradePersonalization } from "./upgrade-personalization";
27
- import { upgradeTickerList } from "./upgrade-tickers";
28
26
 
29
27
  const CONTENT_WIDTH = 64;
30
28
  /** Border plus padding the terminal dialog host draws around the content. */
@@ -117,13 +115,6 @@ export function proStepCopy(offer: UpgradeOffer | null): ProStepCopy {
117
115
  };
118
116
  }
119
117
 
120
- /** The Pro step's first feature; with tickers it names the account's own holdings. */
121
- export function proStepRealtimeTitle(tickers: readonly string[] | null): string {
122
- return tickers?.length
123
- ? tf("Real-time quotes for {tickers}", { tickers: upgradeTickerList(tickers) })
124
- : t("Real-time market data");
125
- }
126
-
127
118
  /** Ranked like the onboarding Pro step: the data first, then what reads it. */
128
119
  const PRO_FEATURES: Array<{ label: string; value: string }> = [
129
120
  { label: "Real-time data", value: "Free runs 15 min behind on quotes, 12 h on news" },
@@ -132,18 +123,9 @@ const PRO_FEATURES: Array<{ label: string; value: string }> = [
132
123
  { label: "Flow and X", value: "Options flow, the X feed and sentiment" },
133
124
  ];
134
125
 
135
- /**
136
- * The feature list, translated. With tickers (the `upgrade_personalized`
137
- * arm) the real-time row names the account's own tickers; without
138
- * them it is exactly the generic list.
139
- */
140
- export function proFeatureRows(tickers: readonly string[] | null): Array<{ label: string; value: string }> {
141
- return PRO_FEATURES.map((feature, index) => ({
142
- label: feature.label,
143
- value: index === 0 && tickers?.length
144
- ? tf("{tickers} quotes, not 15 min behind", { tickers: upgradeTickerList(tickers) })
145
- : t(feature.value),
146
- }));
126
+ /** The feature list, translated. */
127
+ function proFeatureRows(): Array<{ label: string; value: string }> {
128
+ return PRO_FEATURES.map((feature) => ({ label: feature.label, value: t(feature.value) }));
147
129
  }
148
130
 
149
131
  /** Pricing and this account's trial and billing state; never rejects, unknowns come back null. */
@@ -175,7 +157,6 @@ function UpgradeDialog({
175
157
  useAppLanguage();
176
158
  const [interval, setBillingInterval] = useState<CloudBillingInterval>(initialInterval);
177
159
  const [offer, setOffer] = useState<UpgradeOffer | null>(null);
178
- const personalTickers = useUpgradePersonalization("upgrade-sheet", offer !== null && !offer.paymentFailed);
179
160
 
180
161
  useEffect(() => {
181
162
  let live = true;
@@ -233,7 +214,7 @@ function UpgradeDialog({
233
214
  shortcutScope={dialogId}
234
215
  />
235
216
  <Box height={1} />
236
- {proFeatureRows(personalTickers).map((feature) => (
217
+ {proFeatureRows().map((feature) => (
237
218
  <KeyValueRow
238
219
  key={feature.label}
239
220
  label={feature.label}
@@ -0,0 +1,118 @@
1
+ import { createConcurrencyLimiter } from "../utils/concurrency";
2
+ import { ApiRequestError } from "./errors";
3
+
4
+ /**
5
+ * How long a read waits for others: long enough for a board's reads, which
6
+ * reach the client through caches and routing a few at a time, to meet.
7
+ */
8
+ const WINDOW_MS = 4;
9
+
10
+ /**
11
+ * How long a batch route the service answered 404 is left alone before it is
12
+ * asked again: an app that updated before its service, or that reached an
13
+ * instance a deploy had not replaced yet, gets its batches once the service
14
+ * has them.
15
+ */
16
+ export const BATCH_ROUTE_REPROBE_MS = 15 * 60_000;
17
+
18
+ /**
19
+ * Statuses that refuse a batch as asked (no such route, a request too large or
20
+ * not understood), which the reads it carried may each get past alone. A rate
21
+ * limit, an overloaded service or no answer at all is the same for single
22
+ * requests, and more of them is more of what it refused.
23
+ */
24
+ const ASKED_ALONE_AFTER = new Set([400, 404, 413, 422]);
25
+
26
+ /** Whether a batch route's 404 still stands: it is asked again once BATCH_ROUTE_REPROBE_MS has passed. */
27
+ export function createMissingRouteLatch(): { missing(): boolean; refused(error: unknown): void } {
28
+ let until = 0;
29
+ return {
30
+ missing: () => Date.now() < until,
31
+ refused: (error) => {
32
+ if (error instanceof ApiRequestError && error.status === 404) until = Date.now() + BATCH_ROUTE_REPROBE_MS;
33
+ },
34
+ };
35
+ }
36
+
37
+ /**
38
+ * Reads asked in the same moment, sent as batch requests. A read waits a few
39
+ * milliseconds (WINDOW_MS); the reads of one group gathered by then go out
40
+ * together through `batch`, at most `max` a request, each answered with its
41
+ * own item. A lone read goes out on its own, as it always did.
42
+ *
43
+ * A batch refused as asked (ASKED_ALONE_AFTER) has its reads asked one at a
44
+ * time, at most `fallbackConcurrency` at once, and so has every read a batch
45
+ * left out; a 404 (a service without the route) sends every read that way
46
+ * until the route is asked again (BATCH_ROUTE_REPROBE_MS). Any other failure
47
+ * fails every read of the batch with it.
48
+ */
49
+ export function createReadCoalescer<Key, Result>(options: {
50
+ max: number;
51
+ fallbackConcurrency: number;
52
+ group: (key: Key) => string;
53
+ batch: (keys: Key[]) => Promise<Array<Result | undefined>>;
54
+ single: (key: Key) => Promise<Result>;
55
+ }): {
56
+ read: (key: Key) => Promise<Result>;
57
+ /** Whether reads asked together now go out in batches: false while the route's 404 stands. */
58
+ batching: () => boolean;
59
+ } {
60
+ interface Waiting { key: Key; resolve: (result: Result) => void; reject: (error: unknown) => void }
61
+ const pending = new Map<string, Waiting[]>();
62
+ const limit = createConcurrencyLimiter(options.fallbackConcurrency);
63
+ const route = createMissingRouteLatch();
64
+ let scheduled = false;
65
+
66
+ const one = (waiting: Waiting, limited: boolean) => {
67
+ (limited ? limit(() => options.single(waiting.key)) : options.single(waiting.key)).then(waiting.resolve, waiting.reject);
68
+ };
69
+
70
+ const send = async (group: Waiting[]) => {
71
+ if (group.length === 1 || route.missing()) {
72
+ for (const waiting of group) one(waiting, group.length > 1);
73
+ return;
74
+ }
75
+ let results: Array<Result | undefined>;
76
+ try {
77
+ results = await options.batch(group.map((waiting) => waiting.key));
78
+ } catch (error) {
79
+ route.refused(error);
80
+ const alone = error instanceof ApiRequestError && ASKED_ALONE_AFTER.has(error.status ?? 0);
81
+ for (const waiting of group) {
82
+ if (alone) one(waiting, true);
83
+ else waiting.reject(error);
84
+ }
85
+ return;
86
+ }
87
+ group.forEach((waiting, index) => {
88
+ const result = results[index];
89
+ if (result === undefined) one(waiting, true);
90
+ else waiting.resolve(result);
91
+ });
92
+ };
93
+
94
+ const flush = () => {
95
+ scheduled = false;
96
+ const groups = [...pending.values()];
97
+ pending.clear();
98
+ for (const group of groups) {
99
+ for (let start = 0; start < group.length; start += options.max) void send(group.slice(start, start + options.max));
100
+ }
101
+ };
102
+
103
+ return {
104
+ batching: () => !route.missing(),
105
+ read(key) {
106
+ return new Promise<Result>((resolve, reject) => {
107
+ const group = options.group(key);
108
+ const waiting = pending.get(group);
109
+ if (waiting) waiting.push({ key, resolve, reject });
110
+ else pending.set(group, [{ key, resolve, reject }]);
111
+ if (!scheduled) {
112
+ scheduled = true;
113
+ setTimeout(flush, WINDOW_MS);
114
+ }
115
+ });
116
+ },
117
+ };
118
+ }
@@ -3,10 +3,19 @@
3
3
  * as daily levels built from DTCC public dissemination.
4
4
  */
5
5
 
6
+ /**
7
+ * What a day's level rests on: the day's trades, or the clearing house's
8
+ * end-of-day settlement price on a day without enough agreeing trades (its
9
+ * `prints` is then 0). Absent from a server that predates it, which read as
10
+ * `traded`.
11
+ */
12
+ export type CreditLevelKind = "traded" | "settlement";
13
+
6
14
  export interface CreditBoardPoint {
7
15
  date: string;
8
16
  level: number;
9
17
  prints: number;
18
+ kind?: CreditLevelKind;
10
19
  /** The contract that was on the run that day, e.g. "2031-12-20". */
11
20
  maturity: string;
12
21
  /**
@@ -32,6 +41,8 @@ export interface CdxBoardIndex {
32
41
  maturity: string | null;
33
42
  level: number | null;
34
43
  prints: number | null;
44
+ /** What the latest level rests on, as on each point; null without a level. */
45
+ kind?: CreditLevelKind | null;
35
46
  /** HY and EM: the latest level as a conventional spread in bp, as on each point. */
36
47
  spreadBp?: number | null;
37
48
  /**
@@ -71,6 +82,8 @@ export interface SovrBoardSovereign {
71
82
  level: number;
72
83
  prints: number;
73
84
  reported: number;
85
+ /** What the latest level rests on, as on each point. */
86
+ kind?: CreditLevelKind;
74
87
  change1W: number | null;
75
88
  change1M: number | null;
76
89
  points: CreditBoardPoint[];
@@ -17,6 +17,12 @@ export interface CryptoEtfFlowDay {
17
17
  total: number | null;
18
18
  /** Funds that reported the day before but show no figure yet. */
19
19
  pending: string[];
20
+ /**
21
+ * The funds' price move that day: the median of their close-to-close
22
+ * changes, in percent. Null where too few funds traded; absent when the
23
+ * server could not read the closes.
24
+ */
25
+ priceChangePct?: number | null;
20
26
  }
21
27
 
22
28
  /** `GET /cloud/crypto/etf-flows?asset=btc|eth`: daily net flows of the US spot funds. */
@@ -203,3 +203,43 @@ export interface DefiTvlPayload {
203
203
  history: { start: string; total: Array<number | null> } | null;
204
204
  warnings: string[];
205
205
  }
206
+
207
+ /** One value per UTC day, oldest first. */
208
+ export interface BitcoinNetworkDailyValue {
209
+ date: string;
210
+ value: number;
211
+ }
212
+
213
+ /**
214
+ * `GET /cloud/crypto/bitcoin/network`: the bitcoin network's daily hash rate,
215
+ * the difficulty at each retarget, the next retarget's estimate and hashprice,
216
+ * derived from the block rewards, the BTC price and the difficulty.
217
+ */
218
+ export interface BitcoinNetworkPayload {
219
+ version: 1;
220
+ generatedAt: string;
221
+ status: "available" | "stale" | "unavailable";
222
+ /** Who serves the figures, as a chart cites them: Gloom Cloud. */
223
+ source: { name: string; url: string };
224
+ /** When the hash rate and rewards were last read. */
225
+ historyFetchedAt: string | null;
226
+ /** Exahashes per second, each UTC day's average; the newest day is the day so far. */
227
+ hashrate: BitcoinNetworkDailyValue[];
228
+ /** The difficulty each retarget set, dated by its block. */
229
+ difficulty: Array<{ date: string; height: number; difficulty: number; changePercent: number | null }>;
230
+ /** USD per PH/s per day, derived. */
231
+ hashprice: BitcoinNetworkDailyValue[];
232
+ /** The estimate of the next retarget, as last read. */
233
+ retarget: {
234
+ changePercent: number;
235
+ estimatedAt: string;
236
+ nextHeight: number;
237
+ remainingBlocks: number;
238
+ progressPercent: number;
239
+ previousChangePercent: number | null;
240
+ readAt: string;
241
+ } | null;
242
+ /** The estimated change in percent, the last read of each UTC day. */
243
+ retargetHistory: BitcoinNetworkDailyValue[];
244
+ warnings: string[];
245
+ }