@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
@@ -268,7 +268,8 @@ export interface TtmConversion {
268
268
  }
269
269
 
270
270
  /**
271
- * How a served enterprise value ties to market cap + total debt - cash from the latest balance sheet served beside it.
271
+ * How a served enterprise value ties to market cap + total debt (+ leases, `leases`) - cash from the latest balance sheet
272
+ * served beside it.
272
273
  * `matches` within 5%; `differs` beyond it (or beyond 2% on the other side of the market cap from net debt), within
273
274
  * 0.7x to 1.5x, shown labelled as the provider's; `withdrawn` outside that band, with no EV or EV/revenue; `unchecked`
274
275
  * without a recent balance sheet carrying both lines. `computed`: an insurer's or a holding company's EV, which is
@@ -284,15 +285,24 @@ export interface EnterpriseValueCheck {
284
285
  /** The market cap the EV is measured on; absent only on a not-meaningful source EV served without one. */
285
286
  marketCap?: number;
286
287
  totalDebt?: number;
288
+ /** The balance sheet's lease liabilities the bridge adds to total debt, as FA's net debt does (utils/lease-liabilities); absent when none were added. */
289
+ leases?: number;
287
290
  cash?: number;
288
291
  /** YYYY-MM-DD of the balance sheet the debt and cash come from. */
289
292
  balanceSheetDate?: string;
290
- /** marketCap + totalDebt - cash. */
293
+ /** marketCap + totalDebt + leases - cash. */
291
294
  computed?: number;
292
295
  /** `cash` is cash and equivalents alone: an insurer's or a holding company's investments stay in its EV. */
293
296
  investmentsKept?: true;
294
- /** Why the EV is not meaningful (`not-meaningful`). */
297
+ /** Why the EV is not meaningful (`not-meaningful`), or why a withdrawn EV no balance sheet checked is withdrawn. */
295
298
  reason?: string;
299
+ /** A balance sheet in another currency than the market cap: its currency and the rate at its date
300
+ * (`currency` per unit of `from`) that `totalDebt`, `leases` and `cash` were converted at. */
301
+ fx?: { from: string; rate: number };
302
+ /** The provider converted its EV from the statements' currency. */
303
+ convertedFrom?: string;
304
+ /** Withdrawn because the provider applied that conversion twice: its EV over `computed` is the conversion rate. */
305
+ convertedTwice?: true;
296
306
  }
297
307
 
298
308
  /** How a trailing P/E converts the EPS it divides by, when that EPS is in another currency than the price. */
@@ -481,6 +491,18 @@ interface AnalystRecommendationTrend {
481
491
  strongSell?: number;
482
492
  }
483
493
 
494
+ /** Why a firm took an action, as public news coverage of it quotes the firm, word for word. */
495
+ export interface AnalystRatingReason {
496
+ /** One line from the article, as it prints it. */
497
+ text: string;
498
+ /** The article. */
499
+ url: string;
500
+ /** Its publisher, when known. */
501
+ source?: string;
502
+ /** ISO time the article was published. */
503
+ publishedAt?: string;
504
+ }
505
+
484
506
  export interface AnalystRatingRecord {
485
507
  date: string;
486
508
  firm: string;
@@ -489,6 +511,8 @@ export interface AnalystRatingRecord {
489
511
  prior?: string;
490
512
  currentPriceTarget?: number;
491
513
  priorPriceTarget?: number;
514
+ /** Absent when no coverage of the action gives a reason. */
515
+ reason?: AnalystRatingReason;
492
516
  }
493
517
 
494
518
  export interface AnalystEstimateRecord {
@@ -784,6 +808,11 @@ export interface FinancialStatement {
784
808
  date: string;
785
809
  /** Source of the fiscal period date; does not establish metric publication dates. */
786
810
  dateSource?: "sec" | "provider";
811
+ /**
812
+ * The accounting standard the issuer reports in, from the taxonomy of its latest annual report to the SEC (10-K,
813
+ * 20-F or 40-F): BABA's 20-F is US GAAP, NVO's IFRS. Absent for a company that files none with the SEC.
814
+ */
815
+ accountingStandard?: "us-gaap" | "ifrs";
787
816
  /** Original vendor period date when independent filing evidence changes it. */
788
817
  providerDate?: string;
789
818
  /** Filing evidence for the period identity only, not availability of every field. */
@@ -975,12 +1004,20 @@ export interface PricePoint {
975
1004
  * or comparison with a day's count takes it.
976
1005
  */
977
1006
  venueVolume?: { venue: string; volume: number };
1007
+ /**
1008
+ * What the bar's volume counts, when the source says: `aggregate` for a
1009
+ * total across venues (a coin's daily bar), `3 spot venues` for a sum over
1010
+ * those (a coin's intraday bar).
1011
+ */
1012
+ volumeBasis?: string;
978
1013
  /** The bar's period had not ended when it was served: its close is the latest price, and it may have no volume yet. */
979
1014
  partial?: boolean;
980
1015
  /** The bar's prices were rebuilt from shorter bars where the source left it empty or too coarse. */
981
1016
  filled?: boolean;
982
1017
  /** A future's session that has closed but whose settlement is not confirmed yet: its close is the last trade. */
983
1018
  unsettled?: boolean;
1019
+ /** A continuous future's bar (NG=F): the contract it closes on (NGZ26). A change from the bar before is a roll. */
1020
+ contract?: string;
984
1021
  }
985
1022
 
986
1023
  export interface StatementHistoryAttempt {
@@ -127,6 +127,8 @@ export interface HeadlessPaneContext {
127
127
  capabilities?: CapabilityInvoker;
128
128
  /** The catalog's name for the series charted as an expression (`FRED:DFII10`); undefined for one it does not list. */
129
129
  catalogSeriesName?: (expression: string) => string | undefined;
130
+ /** The catalog series a bare word is an alias of (`hashrate` is CAP:bitcoin:hashrate); undefined for any other word. */
131
+ catalogSeriesNamed?: (word: string) => { expression: string; name: string } | undefined;
130
132
  /** Locally registered broker adapters. Reports may read account data; they never submit orders. */
131
133
  resolveBroker?: (brokerType: string) => import("./broker").BrokerAdapter | null;
132
134
  /** Read one local portfolio without passing holdings through a remote endpoint. */
@@ -149,7 +151,9 @@ export interface HeadlessPaneContext {
149
151
  * `coinNote` is what `quote` says of a bare coin ticker read as a listing
150
152
  * that is not the coin (ETH, the Grayscale fund), for the report's warnings.
151
153
  */
152
- resolveListing?: (symbol: string, argumentWith: (key: string) => string) => Promise<{ symbol: string; exchange?: string; name?: string; coinNote?: string } | null>;
154
+ resolveListing?: (symbol: string, argumentWith: (key: string) => string) => Promise<{ symbol: string; exchange?: string; name?: string; coinNote?: string;
155
+ /** What became of the company that had the symbol, as `quote` says it ("GOGL was Golden Ocean Group until 2025, now Cmb.Tech: CMBT"). */
156
+ successorNote?: string } | null>;
153
157
  /**
154
158
  * What a plugin keeps on this device only (its `ctx.resume` state, never
155
159
  * synced), such as ALRT's log of the alerts the app fired; null when none.
@@ -191,6 +195,13 @@ export interface HeadlessPaneColumn {
191
195
  stackRows?: number;
192
196
  /** The text table leaves the column out when fitted to fewer terminal columns than this; exports and piped output keep it. */
193
197
  minTableWidth?: number;
198
+ /**
199
+ * The narrow text table drops the column, rightmost first, before it moves any column under its rows: a figure
200
+ * the others imply (RETURN's interval $ beside its prices). Exports and a table that fits keep it.
201
+ */
202
+ optional?: boolean;
203
+ /** Among optional columns, a higher priority is dropped sooner. */
204
+ dropPriority?: number;
194
205
  description?: string;
195
206
  format?: (value: unknown, row: HeadlessPaneRow) => string;
196
207
  /** What the text report prints when it can say more than an export should (a unit word beside a number); CSV and NDJSON keep `format`. */
@@ -209,9 +220,10 @@ export interface HeadlessPaneColumn {
209
220
  /**
210
221
  * The text report prints the value on its own lines under the row instead
211
222
  * of in a column, for a footnote that belongs to that row; an empty value
212
- * prints nothing. Exports keep it as a column.
223
+ * prints nothing. Exports keep it as a column. `"line"`: one line cut to
224
+ * the width, never wrapped (a story's summary under its headline).
213
225
  */
214
- underRow?: boolean;
226
+ underRow?: boolean | "line";
215
227
  }
216
228
 
217
229
  export interface HeadlessPaneEntry {
@@ -284,6 +296,13 @@ export interface HeadlessPaneFreshness {
284
296
  delayMinutes?: number;
285
297
  /** What not-a-feed data is, in a few words: "filed data", "monthly release", "your inputs". */
286
298
  basis?: string;
299
+ /**
300
+ * The pane shows nothing from a market or a feed: the user's own notes and
301
+ * rules, the app's connections, documentation, an account. A screenshot's
302
+ * footer then carries no status line, which would date nothing or call the
303
+ * app's own state "not a live feed". `fn` still cites `source` and `basis`.
304
+ */
305
+ local?: boolean;
287
306
  /**
288
307
  * How often the data is published, when its dates mark the start of a period
289
308
  * (a monthly statistic is dated the 1st). The report then names the month,
@@ -403,12 +422,24 @@ export interface HeadlessPaneFreshness {
403
422
  * `newest story` dates a news list `newest story Tue 29 Sep 2026 20:17 UTC`.
404
423
  */
405
424
  asOfLabel?: string;
425
+ /**
426
+ * The newest observation is a bar of this many minutes that opens at the
427
+ * as-of: the line names its span, `last bar 15:00–16:00 UTC`, so the bar's
428
+ * open is not read as how far the data runs.
429
+ */
430
+ barMinutes?: number;
406
431
  /**
407
432
  * Say when the rows were retrieved too, after the newest one's date: a list
408
433
  * dated by its newest filing was not read then (`newest filing Tue 27 Oct
409
434
  * 2026 · retrieved Wed 28 Oct 2026 19:07 UTC`).
410
435
  */
411
436
  retrievedToo?: boolean;
437
+ /**
438
+ * When the source last read the data, when that is not now: a page the
439
+ * server reads hourly is retrieved when it read it, not when the report
440
+ * asked the server. An ISO instant; ignored when in the future.
441
+ */
442
+ retrievedAt?: string;
412
443
  /** What the figures are, said after the status: `funding = current estimate, pays 08:00 UTC`. */
413
444
  note?: string;
414
445
  /**
@@ -504,6 +535,13 @@ export interface HeadlessRowsResult extends HeadlessPaneResultBase {
504
535
  export type HeadlessBundleSection =
505
536
  | {
506
537
  title: string;
538
+ /**
539
+ * The heading the text report prints in place of `title`, when it can say
540
+ * more than an export's section name should (the scale its amounts are
541
+ * printed in, "Total revenue, USD millions"). JSON, CSV and NDJSON keep
542
+ * `title`, so a section read by its name stays where it was.
543
+ */
544
+ textTitle?: string;
507
545
  columns?: HeadlessPaneColumn[];
508
546
  rows: HeadlessPaneRow[];
509
547
  /** What the report says when `rows` is empty, in place of "No data.": why there are none, and what to run instead. */
@@ -576,6 +614,7 @@ export type HeadlessBundleSection =
576
614
  /** In a report with `exportDated`: the period the figures cover, and when they were released (an ISO date or instant), which each exported line names in `period` and `released`. */
577
615
  period?: string;
578
616
  released?: string;
617
+ textTitle?: never;
579
618
  columns?: never;
580
619
  rows?: never;
581
620
  textColumns?: never;
@@ -183,7 +183,7 @@ export interface PaneDef {
183
183
  * `headless` model) cites, when "Gloom Cloud" with the state the footer
184
184
  * shows would be wrong: local data, a calculator, filed records.
185
185
  */
186
- reportFreshness?: Pick<HeadlessPaneFreshness, "source" | "status" | "basis">;
186
+ reportFreshness?: Pick<HeadlessPaneFreshness, "source" | "status" | "basis" | "local">;
187
187
  /**
188
188
  * Options a rendered-view report takes (`fn OMON AAPL --strikes 10`):
189
189
  * each sets the pane setting of its key, is checked by its `normalize`, and
@@ -203,7 +203,14 @@ export interface PaneDef {
203
203
  * catalog lists it, and `fn` refuses an argument from a function that
204
204
  * declares none here, in its shortcut or in a `headless` model.
205
205
  */
206
- reportArgument?: Pick<HeadlessPaneArgumentDef, "kind" | "placeholder" | "description" | "optional">;
206
+ reportArgument?: Pick<HeadlessPaneArgumentDef, "kind" | "placeholder" | "description" | "optional"> & {
207
+ /**
208
+ * The argument names something the pane opens by its own id (the story
209
+ * pane's story id), never a symbol: `fn` does not look it up as a ticker.
210
+ * A query (X Feed's) leaves it unset and keeps its ticker reading.
211
+ */
212
+ identifier?: boolean;
213
+ };
207
214
  /**
208
215
  * Lines a rendered-view report prints above its table, from the settings it
209
216
  * ran with: what the default view leaves out and how to see more. `--json`
@@ -220,6 +227,12 @@ export interface PaneDef {
220
227
  * for the symbol (`lock.context` reads it), so the note may resolve later.
221
228
  */
222
229
  reportLockNote?(lock: PaneLock): string | Promise<string>;
230
+ /**
231
+ * The sign-in wall covers the whole pane whenever there is no Gloom Cloud
232
+ * session (ASKG): a rendered-view report without one prints its
233
+ * `reportLockNote` at once rather than render the wall to read it.
234
+ */
235
+ signInWall?: boolean;
223
236
  /**
224
237
  * What a rendered-view report needs before it shows anything, such as a
225
238
  * sign-in: `gloom catalog` lists it under Requires, as it does a
@@ -540,6 +553,13 @@ export interface PaneTemplateDef {
540
553
  listed?: boolean;
541
554
  /** Template-specific headless model. Takes precedence over the pane-level model. */
542
555
  headless?: HeadlessPaneDefinition;
556
+ /**
557
+ * A one-ticker template whose pane also opens on several at once (DVD's
558
+ * ranking): `fn` and `shot` pass a typed list (`shot DVD KO JNJ`) to
559
+ * createInstance as `symbols`. Any other one-ticker template gets the list
560
+ * as it always has, in `symbol` and `arg`.
561
+ */
562
+ opensTickerList?: boolean;
543
563
  /**
544
564
  * Source and status of the view this template opens, for a template that
545
565
  * opens one view of a pane hosting several (Fixed Income's Issuer Debt).
@@ -547,9 +567,16 @@ export interface PaneTemplateDef {
547
567
  * `reportFreshness`: each field set here wins, the rest are the pane's. So
548
568
  * they date the filings on screen, not the issuer's stock quote.
549
569
  */
550
- reportFreshness?: Pick<HeadlessPaneFreshness, "source" | "status" | "basis">;
570
+ reportFreshness?: Pick<HeadlessPaneFreshness, "source" | "status" | "basis" | "local">;
551
571
  wizard?: WizardStep[];
552
572
  canCreate?: (context: PaneTemplateContext, options?: PaneTemplateCreateOptions) => boolean;
573
+ /**
574
+ * Settings shown by catalog discovery without running createInstance. Supply
575
+ * these when opening a pane needs live data or has side effects. An empty
576
+ * object means there are no settings to describe before the pane is opened.
577
+ * When omitted, discovery derives settings from createInstance as before.
578
+ */
579
+ catalogSettings?: Record<string, unknown>;
553
580
  createInstance?: (
554
581
  context: PaneTemplateContext,
555
582
  options?: PaneTemplateCreateOptions,
@@ -962,6 +989,8 @@ export interface AppNotificationRequest {
962
989
  label: string;
963
990
  onClick: () => void;
964
991
  };
992
+ /** Runs once, when the in-app toast is first drawn. Not called when `toast` is false. */
993
+ onShown?: () => void;
965
994
  }
966
995
 
967
996
  export interface BrokerInstanceUpdateOptions {
package/src/ui/host.tsx CHANGED
@@ -375,6 +375,17 @@ export interface ImageSurfaceProps extends BoxProps {
375
375
  src?: string;
376
376
  alt?: string;
377
377
  objectFit?: "contain" | "cover";
378
+ /**
379
+ * Draw `children` until the image has loaded, not only without a `src` or
380
+ * once it fails, so a box that waits on a picture shows its stand-in rather
381
+ * than an empty one. The terminal always does.
382
+ */
383
+ fallbackWhileLoading?: boolean;
384
+ /**
385
+ * A colour behind the picture once it has loaded (a logo made for a light
386
+ * page), never behind `children`. The terminal draws none.
387
+ */
388
+ imageBackground?: string;
378
389
  }
379
390
  export interface MediaSurfaceProps extends BoxProps {
380
391
  src?: string;
@@ -709,7 +720,12 @@ export interface SaveTextFileRequest {
709
720
 
710
721
  export interface RendererHost {
711
722
  requestExit(): void;
712
- startWindowDrag?(): Promise<void> | void;
723
+ /**
724
+ * From a press on a title bar. `press.detail` counts the clicks: where the
725
+ * system's title bars maximize on a double-click, the second press does that
726
+ * instead of moving the window.
727
+ */
728
+ startWindowDrag?(press?: { detail?: number }): Promise<void> | void;
713
729
  controlWindow?(action: "minimize" | "toggle-maximize" | "close"): Promise<void> | void;
714
730
  /**
715
731
  * Opens a link in the person's browser. Resolves false when no browser could
package/src/ui/toast.tsx CHANGED
@@ -1,4 +1,5 @@
1
- import { createContext, useContext, type ComponentType, type ReactNode } from "react";
1
+ import { createContext, useContext, useEffect, useRef, type ComponentType, type ReactNode } from "react";
2
+ import { logFailure } from "../utils/log-failure";
2
3
 
3
4
  /** @public */
4
5
  export interface ToastAction {
@@ -14,6 +15,8 @@ export interface ToastOptions {
14
15
  action?: ToastAction;
15
16
  /** Rendered next to `action`. Use for a dismissing counterpart such as snooze. */
16
17
  secondaryAction?: ToastAction;
18
+ /** Runs once, after a viewport first draws the toast. */
19
+ onShown?(): void;
17
20
  }
18
21
 
19
22
  export interface ToastHost {
@@ -141,6 +144,28 @@ export function useToastHost(): ToastHost {
141
144
  return host;
142
145
  }
143
146
 
147
+ /**
148
+ * Every viewport calls this with the toasts it draws: each toast's `onShown`
149
+ * runs once, after the commit that first puts it on screen.
150
+ */
151
+ export function useToastsShown(toasts: readonly { id: number; options?: ToastOptions }[]): void {
152
+ const shown = useRef(new Set<number>());
153
+ useEffect(() => {
154
+ const current = new Set<number>();
155
+ for (const toast of toasts) {
156
+ current.add(toast.id);
157
+ if (shown.current.has(toast.id)) continue;
158
+ try {
159
+ toast.options?.onShown?.();
160
+ } catch (error) {
161
+ // One failing callback must not keep the others from running.
162
+ logFailure("toast", "A toast's shown callback failed")(error);
163
+ }
164
+ }
165
+ shown.current = current;
166
+ }, [toasts]);
167
+ }
168
+
144
169
  export function ToastViewport(props: { position?: string }) {
145
170
  const { Viewport } = useToastHost();
146
171
  return <Viewport {...props} />;
@@ -0,0 +1,140 @@
1
+ /**
2
+ * Text for a terminal that shows only ASCII: a C locale, or a Windows console
3
+ * on a legacy code page (437, 850, 1252), where UTF-8 bytes print as `—`.
4
+ * What the CLI writes itself keeps its meaning: a dash is `-`, the `·`
5
+ * between a source line's parts `|`, a price in euros `EUR211.25` (as one in
6
+ * kroner is `NOK393.90`) and one in US cents `447.50c`.
7
+ */
8
+
9
+ /** Spelled out before single characters, so the yuan's `CN¥` is not read as the yen's `¥`. */
10
+ const ASCII_SEQUENCES: ReadonlyArray<readonly [string, string]> = [
11
+ ["CN¥", "CNY"],
12
+ ["JP¥", "JPY"],
13
+ ];
14
+
15
+ const ASCII_SPELLINGS: Readonly<Record<string, string>> = {
16
+ // Dashes and the minus sign.
17
+ "\u2012": "-", "\u2013": "-", "\u2014": "-", "\u2015": "-", "\u2212": "-",
18
+ // Separators and marks.
19
+ "\u00B7": "|", "\u2022": "*", "\u2026": "...", "\u00A6": "|",
20
+ // Currencies, as their codes; a minor unit as its letter.
21
+ "\u20AC": "EUR", "\u00A3": "GBP", "\u00A5": "JPY", "\u00A2": "c", "\u20B9": "INR", "\u20A9": "KRW", "\u20AA": "ILS",
22
+ "\u20AB": "VND", "\u20B1": "PHP", "\u20BA": "TRY", "\u20BD": "RUB", "\u20A6": "NGN", "\u20B4": "UAH", "\u20B8": "KZT",
23
+ "\u20BF": "BTC", "\u0E3F": "THB",
24
+ // Quotes and primes.
25
+ "\u2018": "'", "\u2019": "'", "\u201A": "'", "\u201C": "\"", "\u201D": "\"", "\u201E": "\"", "\u2032": "'", "\u2033": "\"",
26
+ "\u00AB": "\"", "\u00BB": "\"",
27
+ // Arithmetic.
28
+ "\u00D7": "x", "\u00F7": "/", "\u00B1": "+/-", "\u2248": "~", "\u2264": "<=", "\u2265": ">=", "\u2260": "!=", "\u00B0": "deg",
29
+ "\u00BC": "1/4", "\u00BD": "1/2", "\u00BE": "3/4", "\u2030": "per mille", "\u00B5": "u",
30
+ // Arrows and markers.
31
+ "\u2192": "->", "\u2190": "<-", "\u2191": "^", "\u2193": "v", "\u25B2": "^", "\u25BC": "v", "\u21B5": "Enter",
32
+ "\u2713": "ok", "\u2714": "ok", "\u2717": "x", "\u2715": "x",
33
+ // Box drawing.
34
+ "\u2502": "|", "\u2500": "-", "\u2503": "|", "\u2501": "-",
35
+ // Spaces.
36
+ "\u00A0": " ", "\u2009": " ", "\u202F": " ", "\u2007": " ", "\u2002": " ", "\u2003": " ",
37
+ // Letters that do not decompose.
38
+ "\u00DF": "ss", "\u00E6": "ae", "\u00C6": "AE", "\u0153": "oe", "\u0152": "OE", "\u00F8": "o", "\u00D8": "O",
39
+ "\u0111": "d", "\u0110": "D", "\u0142": "l", "\u0141": "L", "\u00FE": "th", "\u00DE": "Th", "\u0131": "i",
40
+ // Signs.
41
+ "\u2122": "(TM)", "\u00AE": "(R)", "\u00A9": "(C)",
42
+ };
43
+
44
+ const NON_ASCII = /[^\x00-\x7F]/;
45
+ const COMBINING_MARKS = /[\u0300-\u036F]/g;
46
+
47
+ /**
48
+ * `text` in ASCII: each character above with its spelling, an accented letter
49
+ * without its accent (Société Générale is Societe Generale), a box or block
50
+ * drawing character as `|`, `-`, `+` or `#`, and anything else as `?`.
51
+ * Escape sequences (colour) are ASCII and pass through.
52
+ */
53
+ export function asciiText(text: string): string {
54
+ if (!NON_ASCII.test(text)) return text;
55
+ let folded = text;
56
+ for (const [sequence, spelling] of ASCII_SEQUENCES) folded = folded.split(sequence).join(spelling);
57
+ let out = "";
58
+ for (const character of folded) {
59
+ if (character.charCodeAt(0) < 0x80) {
60
+ out += character;
61
+ continue;
62
+ }
63
+ const spelled = ASCII_SPELLINGS[character];
64
+ if (spelled !== undefined) {
65
+ out += spelled;
66
+ continue;
67
+ }
68
+ const bare = character.normalize("NFD").replace(COMBINING_MARKS, "");
69
+ if (bare && !NON_ASCII.test(bare)) {
70
+ out += bare;
71
+ continue;
72
+ }
73
+ const code = character.codePointAt(0)!;
74
+ // Box drawing (U+2500-257F): corners and joins as +; block elements (U+2580-259F), a bar or sparkline's, as #.
75
+ out += code >= 0x2500 && code <= 0x257F ? "+" : code >= 0x2580 && code <= 0x259F ? "#" : "?";
76
+ }
77
+ return out;
78
+ }
79
+
80
+ type LocaleEnv = Readonly<Record<string, string | undefined>>;
81
+
82
+ /**
83
+ * The locale text is written in, by the variable POSIX reads first (LC_ALL,
84
+ * then LC_CTYPE, then LANG; an empty one is unset), or null when none is set.
85
+ */
86
+ function localeName(env: LocaleEnv): string | null {
87
+ return env.LC_ALL || env.LC_CTYPE || env.LANG || null;
88
+ }
89
+
90
+ /**
91
+ * Whether the terminal may not read UTF-8: a locale that names no UTF-8
92
+ * (`C`, `POSIX`, `en_US.ISO-8859-1`), or a Windows shell that sets none, whose
93
+ * console code page then decides (`consoleReadsUtf8`). A locale that is UTF-8,
94
+ * or none set elsewhere, is taken to read it.
95
+ */
96
+ export function localeMayNotReadUtf8(env: LocaleEnv = process.env, platform: string = process.platform): boolean {
97
+ const locale = localeName(env);
98
+ if (locale) return !/utf-?8/i.test(locale);
99
+ return platform === "win32";
100
+ }
101
+
102
+ /**
103
+ * Where Windows keeps `chcp.com`. Windows looks a bare program name up in the
104
+ * current folder before the system's, so a `chcp.com` left in the folder a
105
+ * command runs in would run in its place; the full path never does.
106
+ */
107
+ export function windowsChcpPath(env: Readonly<Record<string, string | undefined>> = process.env): string {
108
+ const root = [env.SystemRoot, env.SYSTEMROOT, env.windir, env.WINDIR]
109
+ .find((dir): dir is string => !!dir && /^[A-Za-z]:[\\/]/.test(dir)) ?? "C:\\Windows";
110
+ return `${root.replace(/[\\/]+$/, "")}\\System32\\chcp.com`;
111
+ }
112
+
113
+ /** The console's code page as `chcp` prints it ("Active code page: 437"), or null when it cannot be read. */
114
+ function consoleCodePage(): number | null {
115
+ try {
116
+ if (typeof Bun === "undefined" || process.platform !== "win32") return null;
117
+ const answer = Bun.spawnSync([windowsChcpPath()], { stdout: "pipe", stderr: "ignore" });
118
+ const page = /(\d+)\D*$/.exec(answer.stdout.toString().trim());
119
+ return page ? Number(page[1]) : null;
120
+ } catch {
121
+ // Intentional ignore: a console whose code page cannot be read is left to show what it gets.
122
+ return null;
123
+ }
124
+ }
125
+
126
+ /**
127
+ * Whether the terminal reads UTF-8: by the locale when one is set, else on
128
+ * Windows by the console's code page (65001 is UTF-8). A code page that
129
+ * cannot be read is taken to read it, so nothing changes where it is unknown.
130
+ */
131
+ export function localeReadsUtf8(
132
+ env: LocaleEnv = process.env,
133
+ platform: string = process.platform,
134
+ codePage: () => number | null = consoleCodePage,
135
+ ): boolean {
136
+ if (!localeMayNotReadUtf8(env, platform)) return true;
137
+ if (localeName(env)) return false;
138
+ const page = codePage();
139
+ return page == null || page === 65001;
140
+ }