gloomberb 0.18.3 → 0.18.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (886) hide show
  1. package/README.md +8 -8
  2. package/README.zh-CN.md +11 -11
  3. package/bin/{gloomberb → gloom} +3 -1
  4. package/package.json +6 -2
  5. package/src/account/checkout-handoff.tsx +225 -0
  6. package/src/account/device-signin-dialog.tsx +2 -2
  7. package/src/account/device-signin.ts +2 -2
  8. package/src/account/upgrade-dialog.tsx +1 -1
  9. package/src/api-client/askg.ts +2 -2
  10. package/src/api-client/auth.ts +2 -2
  11. package/src/api-client/central-bank-rates.ts +6 -0
  12. package/src/api-client/collections.ts +5 -1
  13. package/src/api-client/cot.ts +2 -0
  14. package/src/api-client/crypto-etf-flows.ts +37 -0
  15. package/src/api-client/crypto-markets.ts +60 -0
  16. package/src/api-client/data.ts +84 -5
  17. package/src/api-client/doe.ts +15 -0
  18. package/src/api-client/equity-screener.ts +28 -0
  19. package/src/api-client/exchange-announcements.ts +38 -0
  20. package/src/api-client/fund-facts.ts +39 -0
  21. package/src/api-client/futures-curve.ts +9 -1
  22. package/src/api-client/hiring.ts +301 -0
  23. package/src/api-client/index.ts +22 -5
  24. package/src/api-client/market-discovery.ts +14 -0
  25. package/src/api-client/members.ts +6 -0
  26. package/src/api-client/mna.ts +6 -0
  27. package/src/api-client/paths.ts +18 -1
  28. package/src/api-client/request.ts +21 -4
  29. package/src/api-client/short-side-publications.ts +37 -0
  30. package/src/api-client/socket.ts +64 -4
  31. package/src/api-client/swap-curve.ts +35 -0
  32. package/src/api-client/themes.ts +7 -1
  33. package/src/api-client/types.ts +90 -2
  34. package/src/app/pane-runtime/plugin-bindings.ts +9 -2
  35. package/src/app/runtime/desktop-deeplink.ts +5 -5
  36. package/src/app/runtime/plugin-bindings.ts +2 -2
  37. package/src/app/runtime/startup.ts +13 -0
  38. package/src/app/star-prompt/status-line.tsx +2 -2
  39. package/src/architecture/core-builtin-allowlist.json +5 -2
  40. package/src/architecture/ui-literals-allowlist.json +3 -3
  41. package/src/architecture/ui-tokens-allowlist.json +1 -1
  42. package/src/brokers/broker-portfolio-sync.ts +37 -0
  43. package/src/brokers/directory.ts +11 -0
  44. package/src/brokers/logos.ts +3 -1
  45. package/src/brokers/signed-in/adapter.ts +304 -26
  46. package/src/brokers/signed-in/client.ts +14 -2
  47. package/src/brokers/signed-in/connect.ts +10 -2
  48. package/src/brokers/sync-broker-instance.ts +9 -1
  49. package/src/capabilities/chart-series.ts +22 -6
  50. package/src/cli/bank-section.ts +1 -1
  51. package/src/cli/base-converter.ts +23 -14
  52. package/src/cli/central-bank-events.ts +1 -1
  53. package/src/cli/command-options.ts +59 -4
  54. package/src/cli/commands/api.ts +9 -6
  55. package/src/cli/commands/broker.ts +2 -2
  56. package/src/cli/commands/command-utils.ts +2 -2
  57. package/src/cli/commands/crypto-hints.ts +7 -20
  58. package/src/cli/commands/fred-series.ts +4 -2
  59. package/src/cli/commands/keybindings.ts +2 -2
  60. package/src/cli/commands/market.ts +1117 -264
  61. package/src/cli/commands/news-hints.ts +2 -2
  62. package/src/cli/commands/news-search.ts +59 -6
  63. package/src/cli/commands/options-leaps.ts +41 -26
  64. package/src/cli/commands/overview.ts +121 -48
  65. package/src/cli/commands/plugins.ts +9 -9
  66. package/src/cli/commands/remote.ts +13 -10
  67. package/src/cli/commands/search.ts +64 -44
  68. package/src/cli/commands/system.ts +27 -19
  69. package/src/cli/commands/themes.ts +1 -1
  70. package/src/cli/commands/ticker.ts +192 -47
  71. package/src/cli/context.ts +3 -2
  72. package/src/cli/desktop-pane-shot-view.ts +2 -2
  73. package/src/cli/desktop-pane-shot.ts +1 -1
  74. package/src/cli/earnings-calendar.ts +4 -4
  75. package/src/cli/entry.ts +18 -1
  76. package/src/cli/errors.ts +20 -2
  77. package/src/cli/exit-codes.ts +1 -1
  78. package/src/cli/export-source.ts +10 -4
  79. package/src/cli/freshness.ts +2 -8
  80. package/src/cli/fx-forward.ts +130 -0
  81. package/src/cli/fx-pair.ts +10 -9
  82. package/src/cli/glossary.ts +64 -20
  83. package/src/cli/help.ts +19 -13
  84. package/src/cli/history-export.ts +126 -0
  85. package/src/cli/history-rows.ts +196 -43
  86. package/src/cli/index-roots.ts +5 -45
  87. package/src/cli/index.ts +24 -18
  88. package/src/cli/known-gaps.ts +118 -25
  89. package/src/cli/listing-arg.ts +300 -41
  90. package/src/cli/name-entries.ts +30 -18
  91. package/src/cli/native-smoke.ts +2 -0
  92. package/src/cli/not-a-ticker.ts +19 -9
  93. package/src/cli/opentui-libc.ts +5 -0
  94. package/src/cli/options.ts +12 -0
  95. package/src/cli/pane-functions/capabilities.ts +75 -20
  96. package/src/cli/pane-functions/catalog.ts +24 -23
  97. package/src/cli/pane-functions/discovery.ts +1 -1
  98. package/src/cli/pane-functions/dom.ts +10 -7
  99. package/src/cli/pane-functions/financial-ratio-shot.ts +2 -2
  100. package/src/cli/pane-functions/freshness.ts +174 -23
  101. package/src/cli/pane-functions/function-help.ts +66 -27
  102. package/src/cli/pane-functions/headless.ts +24 -11
  103. package/src/cli/pane-functions/index.ts +18 -16
  104. package/src/cli/pane-functions/options.ts +22 -2
  105. package/src/cli/pane-functions/report-notices.ts +12 -4
  106. package/src/cli/pane-functions/report.ts +5 -5
  107. package/src/cli/pane-functions/resolver.ts +47 -10
  108. package/src/cli/pane-functions/screenshot-assessment.ts +322 -0
  109. package/src/cli/pane-functions/screenshot-bridge.ts +152 -0
  110. package/src/cli/pane-functions/screenshot-chart-evidence.ts +396 -0
  111. package/src/cli/pane-functions/screenshot-data-evidence.ts +383 -0
  112. package/src/cli/pane-functions/screenshot-evidence.ts +1 -1
  113. package/src/cli/pane-functions/screenshot-payload.ts +453 -0
  114. package/src/cli/pane-functions/screenshot-render.ts +316 -0
  115. package/src/cli/pane-functions/screenshot-types.ts +162 -0
  116. package/src/cli/pane-functions/shot-options.ts +8 -3
  117. package/src/cli/peso-dollar-rates.ts +79 -0
  118. package/src/cli/quote-answer.ts +38 -3
  119. package/src/cli/report-tables.ts +61 -16
  120. package/src/cli/restore-plugins.ts +29 -14
  121. package/src/cli/result.ts +111 -22
  122. package/src/cli/series-search.ts +5 -5
  123. package/src/cli/statement-filings.ts +19 -0
  124. package/src/cli/suffixed-listing-rows.ts +49 -0
  125. package/src/cli/symbol-args.ts +50 -15
  126. package/src/cli/symbol-cells.ts +120 -0
  127. package/src/cli/symbol-list.ts +198 -68
  128. package/src/cli/symbol-rows.ts +131 -25
  129. package/src/cli/ticker-resolution.ts +108 -11
  130. package/src/cli/treasury-yields.ts +5 -5
  131. package/src/cli/types.ts +2 -0
  132. package/src/cli/uncovered-instrument.ts +3 -3
  133. package/src/cli/unknown-command.ts +6 -6
  134. package/src/components/chart/composite/chart-layout.ts +131 -0
  135. package/src/components/chart/composite/composite-chart.tsx +373 -16
  136. package/src/components/chart/composite/interactions.ts +7 -2
  137. package/src/components/chart/composite/legend.tsx +75 -3
  138. package/src/components/chart/composite/levels.ts +5 -0
  139. package/src/components/chart/composite/panel-gestures.ts +41 -0
  140. package/src/components/chart/composite/panel-labels.ts +2 -1
  141. package/src/components/chart/composite/panel-surface.tsx +305 -11
  142. package/src/components/chart/composite/price-axis-labels.tsx +27 -3
  143. package/src/components/chart/composite/rasterizer.ts +44 -19
  144. package/src/components/chart/composite/scene.ts +16 -4
  145. package/src/components/chart/composite/text-renderer.ts +48 -21
  146. package/src/components/chart/composite/toolbar.tsx +52 -5
  147. package/src/components/chart/composite/types.ts +13 -0
  148. package/src/components/chart/composite/use-composite-chart-keyboard.ts +120 -13
  149. package/src/components/chart/composite/use-composite-value-scales.ts +44 -0
  150. package/src/components/chart/composite/use-composite-viewport.ts +12 -3
  151. package/src/components/chart/composite/value-scale.ts +149 -0
  152. package/src/components/chart/composite/volume-profile-paint.ts +6 -3
  153. package/src/components/chart/core/pointer.ts +2 -0
  154. package/src/components/chart-table/index.ts +2 -0
  155. package/src/components/chart-table/read.tsx +74 -0
  156. package/src/components/command-bar/commands/collection-list.ts +41 -19
  157. package/src/components/command-bar/commands/collection.ts +9 -3
  158. package/src/components/command-bar/commands/direct/index.ts +1 -1
  159. package/src/components/command-bar/commands/direct/runtime.ts +3 -2
  160. package/src/components/command-bar/pane-templates/items.ts +59 -6
  161. package/src/components/command-bar/pane-templates/workflow.ts +10 -1
  162. package/src/components/command-bar/routes/root/plugin-install.ts +1 -1
  163. package/src/components/command-bar/routes/root/provider-search.ts +42 -11
  164. package/src/components/command-bar/routes/root/results.ts +18 -4
  165. package/src/components/command-bar/routes/root/runtime.ts +15 -3
  166. package/src/components/command-bar/routes/root/search-providers.ts +25 -2
  167. package/src/components/command-bar/routes/root/selection.ts +6 -1
  168. package/src/components/command-bar/routes/root/shortcut-feedback.ts +4 -1
  169. package/src/components/command-bar/routes/root/shortcuts.ts +30 -3
  170. package/src/components/command-bar/routes/ticker-search/results.ts +73 -4
  171. package/src/components/command-bar/selection-runtime.ts +50 -10
  172. package/src/components/command-bar/surface/index.tsx +24 -2
  173. package/src/components/command-bar/view-model.ts +7 -0
  174. package/src/components/command-bar/workflow/broker.ts +2 -2
  175. package/src/components/command-bar/workflow/collection-actions.ts +46 -7
  176. package/src/components/command-bar/workflow/collection-ticker.ts +32 -4
  177. package/src/components/command-bar/workflow/fields.ts +8 -2
  178. package/src/components/command-bar/workflow/ops.ts +18 -4
  179. package/src/components/command-bar/workflow/portfolio-position.ts +53 -4
  180. package/src/components/command-bar/workflow/submit.ts +3 -2
  181. package/src/components/command-bar/workflow/tickers.ts +5 -1
  182. package/src/components/company-logo.tsx +39 -0
  183. package/src/components/data-table/sections.ts +4 -2
  184. package/src/components/form-modal/confirm.tsx +2 -1
  185. package/src/components/form-modal/request.ts +5 -0
  186. package/src/components/form-modal/routes.ts +4 -1
  187. package/src/components/index.ts +12 -6
  188. package/src/components/layout/header.tsx +7 -6
  189. package/src/components/layout/market-summary.ts +9 -6
  190. package/src/components/layout/pane/capture-status.ts +1 -1
  191. package/src/components/layout/pane/footer/model.ts +11 -5
  192. package/src/components/layout/shell/chrome.ts +19 -6
  193. package/src/components/layout/shell/index.tsx +2 -1
  194. package/src/components/layout/shell/pane/layers.tsx +19 -1
  195. package/src/components/layout/status-bar.tsx +2 -2
  196. package/src/components/market-board/index.tsx +11 -3
  197. package/src/components/onboarding/onboarding-wizard.tsx +1 -0
  198. package/src/components/onboarding/portfolio-step/broker-setup-panel.tsx +2 -2
  199. package/src/components/onboarding/wizard-broker-sync.ts +4 -1
  200. package/src/components/pane-settings-dialog/desktop.tsx +20 -7
  201. package/src/components/pane-settings-dialog/tui.tsx +17 -9
  202. package/src/components/pane-settings-dialog/value.ts +8 -1
  203. package/src/components/pane-settings-dialog.tsx +44 -13
  204. package/src/components/sign-in-code-panel.tsx +27 -19
  205. package/src/components/ui/column-grid.tsx +48 -4
  206. package/src/components/ui/country-flag-art.tsx +180 -0
  207. package/src/components/ui/country-flag.tsx +118 -12
  208. package/src/components/ui/data-table/opentui/index.tsx +61 -2
  209. package/src/components/ui/data-table/opentui/model.ts +109 -2
  210. package/src/components/ui/data-table/types.ts +1 -1
  211. package/src/components/ui/display.tsx +5 -1
  212. package/src/components/ui/index.ts +3 -1
  213. package/src/components/ui/logo-mark.tsx +11 -2
  214. package/src/components/ui/query-bar.tsx +1 -1
  215. package/src/components/ui/row-notes.ts +79 -0
  216. package/src/core/state/app/layout.ts +4 -4
  217. package/src/data/cached-query.ts +8 -1
  218. package/src/data/config/chart-settings.ts +3 -3
  219. package/src/data/config/home.ts +10 -2
  220. package/src/data/config/layout.ts +4 -1
  221. package/src/data/config/store/node.ts +4 -0
  222. package/src/data/config/store/normalize.ts +13 -3
  223. package/src/data/config/store/portfolio-as-of-column.ts +2 -2
  224. package/src/data/json-storage.ts +2 -0
  225. package/src/data/saved-copies.ts +84 -0
  226. package/src/docs/snapshot.json +65 -32
  227. package/src/i18n/es.ts +29 -12
  228. package/src/i18n/ja.ts +29 -12
  229. package/src/i18n/ko.ts +29 -12
  230. package/src/i18n/zh-cn.ts +29 -12
  231. package/src/i18n/zh-tw.ts +29 -12
  232. package/src/layout/desks.ts +1 -1
  233. package/src/layout/launch-layout.ts +1 -1
  234. package/src/layout/pane-manager/floating-actions.ts +5 -3
  235. package/src/layout/pane-manager/floating.ts +43 -1
  236. package/src/layout/pane-manager/index.ts +2 -0
  237. package/src/layout/selected-ticker.ts +74 -0
  238. package/src/market-data/depositary-pair.ts +251 -0
  239. package/src/market-data/futures-board.ts +1 -1
  240. package/src/market-data/futures-contract.ts +124 -40
  241. package/src/market-data/fx-closes.ts +17 -2
  242. package/src/market-data/hooks.tsx +19 -11
  243. package/src/market-data/market/change-basis.ts +49 -7
  244. package/src/market-data/market/freshness.ts +34 -5
  245. package/src/market-data/market/period-return.ts +163 -0
  246. package/src/market-data/market/trading-sessions.ts +13 -0
  247. package/src/market-data/market/year-to-date.ts +8 -13
  248. package/src/market-data/performance.ts +20 -14
  249. package/src/market-data/perpetual-premium.ts +32 -0
  250. package/src/market-data/published-apac-sessions.ts +2 -1
  251. package/src/market-data/published-futures-sessions.ts +69 -0
  252. package/src/market-data/quotes/contributions.ts +5 -1
  253. package/src/market-data/quotes/freshness.ts +42 -0
  254. package/src/market-data/quotes/intraday-bar.ts +37 -0
  255. package/src/market-data/quotes/regular-session-valuation.ts +13 -8
  256. package/src/market-data/quotes/resolution.ts +4 -2
  257. package/src/market-data/tax-equivalent.ts +1 -1
  258. package/src/market-data/ticker-price-returns.ts +3 -1
  259. package/src/news/aggregator.ts +5 -1
  260. package/src/news/news-model.ts +4 -0
  261. package/src/news/types.ts +11 -0
  262. package/src/notifications/app-notifier.ts +1 -1
  263. package/src/plugins/auto-update.ts +2 -2
  264. package/src/plugins/builtin/account-management/index.tsx +1 -0
  265. package/src/plugins/builtin/account-management/pane.tsx +9 -8
  266. package/src/plugins/builtin/alerts/alert-engine.ts +29 -19
  267. package/src/plugins/builtin/alerts/calendar-events.ts +378 -0
  268. package/src/plugins/builtin/alerts/cli.ts +485 -76
  269. package/src/plugins/builtin/alerts/command.ts +5 -10
  270. package/src/plugins/builtin/alerts/event-rows.ts +9 -5
  271. package/src/plugins/builtin/alerts/events-pane.tsx +71 -56
  272. package/src/plugins/builtin/alerts/events.ts +107 -5
  273. package/src/plugins/builtin/alerts/fired-log.ts +78 -0
  274. package/src/plugins/builtin/alerts/format.ts +2 -1
  275. package/src/plugins/builtin/alerts/headless.ts +100 -39
  276. package/src/plugins/builtin/alerts/history-pane.tsx +105 -62
  277. package/src/plugins/builtin/alerts/history-rows.ts +89 -0
  278. package/src/plugins/builtin/alerts/index.tsx +45 -18
  279. package/src/plugins/builtin/alerts/iv-level.ts +365 -0
  280. package/src/plugins/builtin/alerts/levels.ts +3 -3
  281. package/src/plugins/builtin/alerts/pane.tsx +97 -29
  282. package/src/plugins/builtin/alerts/price.ts +35 -0
  283. package/src/plugins/builtin/alerts/quotes.ts +24 -0
  284. package/src/plugins/builtin/alerts/research-builder.ts +84 -11
  285. package/src/plugins/builtin/alerts/research-rules.ts +76 -3
  286. package/src/plugins/builtin/alerts/scheduled-check.ts +206 -32
  287. package/src/plugins/builtin/alerts/scheduled-sources.ts +26 -3
  288. package/src/plugins/builtin/alerts/scheduled.ts +188 -29
  289. package/src/plugins/builtin/alerts/storage.ts +13 -10
  290. package/src/plugins/builtin/alerts/targets.ts +12 -3
  291. package/src/plugins/builtin/analytics/index.tsx +8 -2
  292. package/src/plugins/builtin/analytics/metrics.ts +1 -1
  293. package/src/plugins/builtin/analytics/risk-book.ts +215 -0
  294. package/src/plugins/builtin/analytics/risk-client.ts +13 -6
  295. package/src/plugins/builtin/analytics/risk-headless.ts +55 -21
  296. package/src/plugins/builtin/analytics/risk-math.ts +6 -3
  297. package/src/plugins/builtin/analytics/risk-model.ts +297 -104
  298. package/src/plugins/builtin/analytics/risk-options.ts +17 -2
  299. package/src/plugins/builtin/analytics/risk-pane.tsx +97 -36
  300. package/src/plugins/builtin/attention/pane.tsx +6 -2
  301. package/src/plugins/builtin/awards/headless.ts +7 -3
  302. package/src/plugins/builtin/awards/model.ts +18 -0
  303. package/src/plugins/builtin/awards/pane.tsx +6 -3
  304. package/src/plugins/builtin/backtest/headless.ts +3 -3
  305. package/src/plugins/builtin/backtest/rules.ts +41 -5
  306. package/src/plugins/builtin/broker-manager/add-flow.tsx +12 -7
  307. package/src/plugins/builtin/broker-manager/detail.tsx +47 -19
  308. package/src/plugins/builtin/broker-manager/footer.ts +27 -11
  309. package/src/plugins/builtin/broker-manager/index.tsx +21 -12
  310. package/src/plugins/builtin/broker-manager/keyboard.ts +1 -1
  311. package/src/plugins/builtin/broker-manager/model.ts +12 -2
  312. package/src/plugins/builtin/broker-manager/pane-actions.tsx +183 -57
  313. package/src/plugins/builtin/broker-manager/table.ts +28 -12
  314. package/src/plugins/builtin/broker-trading/account-picker.tsx +2 -1
  315. package/src/plugins/builtin/broker-trading/chart-levels.ts +82 -13
  316. package/src/plugins/builtin/broker-trading/controller.ts +45 -13
  317. package/src/plugins/builtin/broker-trading/dock.tsx +22 -4
  318. package/src/plugins/builtin/broker-trading/headless.ts +2 -1
  319. package/src/plugins/builtin/broker-trading/index.tsx +7 -1
  320. package/src/plugins/builtin/broker-trading/linked-orders.ts +148 -0
  321. package/src/plugins/builtin/broker-trading/order-feed.ts +75 -7
  322. package/src/plugins/builtin/broker-trading/orders.tsx +109 -31
  323. package/src/plugins/builtin/broker-trading/overview-orders.tsx +9 -3
  324. package/src/plugins/builtin/broker-trading/pane-model.ts +30 -2
  325. package/src/plugins/builtin/broker-trading/pane.tsx +110 -23
  326. package/src/plugins/builtin/broker-trading/ticket-parts.tsx +36 -7
  327. package/src/plugins/builtin/broker-trading/ticket.tsx +112 -31
  328. package/src/plugins/builtin/buildout/cells.tsx +4 -0
  329. package/src/plugins/builtin/buildout/detail/index.tsx +5 -1
  330. package/src/plugins/builtin/buildout/detail/ui.tsx +7 -4
  331. package/src/plugins/builtin/buildout/pane/index.tsx +25 -12
  332. package/src/plugins/builtin/buildout/pane/status.tsx +0 -4
  333. package/src/plugins/builtin/builtin-plugin-meta.ts +1 -1
  334. package/src/plugins/builtin/catalysts/detail.tsx +3 -2
  335. package/src/plugins/builtin/catalysts/index.tsx +1 -1
  336. package/src/plugins/builtin/catalysts/model.ts +49 -4
  337. package/src/plugins/builtin/catalysts/pane.tsx +6 -8
  338. package/src/plugins/builtin/central-bank-rates/client.ts +5 -0
  339. package/src/plugins/builtin/central-bank-rates/headless.ts +36 -10
  340. package/src/plugins/builtin/central-bank-rates/model.ts +33 -8
  341. package/src/plugins/builtin/changelog/index.tsx +1 -0
  342. package/src/plugins/builtin/chart-composer/catalog-inventory.ts +1 -0
  343. package/src/plugins/builtin/chart-composer/chart-spec-edit.ts +2 -1
  344. package/src/plugins/builtin/chart-composer/chart-spec.ts +7 -0
  345. package/src/plugins/builtin/chart-composer/cli-options.ts +2 -5
  346. package/src/plugins/builtin/chart-composer/data-catalog-pane.tsx +2 -1
  347. package/src/plugins/builtin/chart-composer/editor/controller.ts +2 -0
  348. package/src/plugins/builtin/chart-composer/editor.tsx +4 -1
  349. package/src/plugins/builtin/chart-composer/headless-schema.ts +28 -26
  350. package/src/plugins/builtin/chart-composer/headless.ts +253 -35
  351. package/src/plugins/builtin/chart-composer/index.tsx +12 -2
  352. package/src/plugins/builtin/chart-composer/leverage-overlay.ts +142 -0
  353. package/src/plugins/builtin/chart-composer/pane.tsx +127 -28
  354. package/src/plugins/builtin/chart-composer/series-catalog.ts +1 -0
  355. package/src/plugins/builtin/chart-composer/series-expression.ts +65 -6
  356. package/src/plugins/builtin/chart-composer/session-history.ts +15 -21
  357. package/src/plugins/builtin/chart-composer/session-range.ts +4 -2
  358. package/src/plugins/builtin/chart-composer/settings.ts +31 -19
  359. package/src/plugins/builtin/chart-composer/use-series-catalog.ts +5 -6
  360. package/src/plugins/builtin/chart-composer/viewport-labels.ts +18 -8
  361. package/src/plugins/builtin/chat/attachments/model.ts +3 -1
  362. package/src/plugins/builtin/chat/content/index.tsx +1 -1
  363. package/src/plugins/builtin/chat/pane-links/open.ts +1 -1
  364. package/src/plugins/builtin/chat/people.ts +1 -1
  365. package/src/plugins/builtin/clinical-trials/client.ts +5 -2
  366. package/src/plugins/builtin/clinical-trials/model.ts +13 -4
  367. package/src/plugins/builtin/clinical-trials/pane.tsx +32 -12
  368. package/src/plugins/builtin/clinical-trials/ticker-sponsor.ts +17 -0
  369. package/src/plugins/builtin/cloud/askg/controller.ts +1 -1
  370. package/src/plugins/builtin/cloud/askg/lock-note.ts +1 -1
  371. package/src/plugins/builtin/cloud/askg/tool-display.ts +1 -1
  372. package/src/plugins/builtin/cloud/auth-commands.ts +3 -3
  373. package/src/plugins/builtin/cloud/team/pane-sections.tsx +105 -47
  374. package/src/plugins/builtin/cloud/team/pane-ui.tsx +42 -4
  375. package/src/plugins/builtin/cloud/team/pane.tsx +204 -64
  376. package/src/plugins/builtin/cloud/thesis/store.ts +45 -22
  377. package/src/plugins/builtin/cloud-tweets/registration.ts +1 -0
  378. package/src/plugins/builtin/commodities-energy/index.tsx +29 -2
  379. package/src/plugins/builtin/commodities-energy/view-state.ts +2 -0
  380. package/src/plugins/builtin/commodity-balances/pane.tsx +11 -4
  381. package/src/plugins/builtin/company-attention/app-rank.tsx +7 -5
  382. package/src/plugins/builtin/company-attention/building-model.ts +222 -0
  383. package/src/plugins/builtin/company-attention/building.tsx +172 -0
  384. package/src/plugins/builtin/company-attention/client.ts +117 -1
  385. package/src/plugins/builtin/company-attention/evidence.ts +16 -3
  386. package/src/plugins/builtin/company-attention/headless.ts +101 -5
  387. package/src/plugins/builtin/company-attention/index.tsx +6 -3
  388. package/src/plugins/builtin/company-attention/model.ts +33 -7
  389. package/src/plugins/builtin/company-attention/moves-model.ts +253 -0
  390. package/src/plugins/builtin/company-attention/moves.tsx +159 -0
  391. package/src/plugins/builtin/company-attention/pane.tsx +79 -23
  392. package/src/plugins/builtin/company-attention/signals-model.ts +229 -0
  393. package/src/plugins/builtin/company-attention/signals.tsx +160 -0
  394. package/src/plugins/builtin/company-kpis/headless.ts +3 -2
  395. package/src/plugins/builtin/company-kpis/model.ts +2 -2
  396. package/src/plugins/builtin/company-kpis/pane.tsx +1 -1
  397. package/src/plugins/builtin/composite-plugins.ts +2 -1
  398. package/src/plugins/builtin/congress-trades/headless.ts +1 -1
  399. package/src/plugins/builtin/connections/index.ts +1 -0
  400. package/src/plugins/builtin/correlation/headless-schema.ts +3 -2
  401. package/src/plugins/builtin/correlation/headless.ts +5 -3
  402. package/src/plugins/builtin/cot/headless.ts +28 -6
  403. package/src/plugins/builtin/cot/model.ts +12 -0
  404. package/src/plugins/builtin/cot/pane.tsx +3 -2
  405. package/src/plugins/builtin/cpi/headless.ts +5 -1
  406. package/src/plugins/builtin/cpi/pane.tsx +11 -9
  407. package/src/plugins/builtin/credit-boards/model.ts +2 -0
  408. package/src/plugins/builtin/credit-documents/headless.ts +1 -1
  409. package/src/plugins/builtin/crypto-board/client.ts +86 -0
  410. package/src/plugins/builtin/crypto-board/defi-view.tsx +218 -0
  411. package/src/plugins/builtin/crypto-board/defi.ts +239 -0
  412. package/src/plugins/builtin/crypto-board/headless.ts +117 -6
  413. package/src/plugins/builtin/crypto-board/index.tsx +8 -3
  414. package/src/plugins/builtin/crypto-board/model.ts +40 -8
  415. package/src/plugins/builtin/crypto-board/pane.tsx +55 -21
  416. package/src/plugins/builtin/crypto-board/series.ts +19 -1
  417. package/src/plugins/builtin/crypto-etf-flows/client.ts +60 -0
  418. package/src/plugins/builtin/crypto-etf-flows/headless.ts +132 -0
  419. package/src/plugins/builtin/crypto-etf-flows/index.tsx +44 -0
  420. package/src/plugins/builtin/crypto-etf-flows/model.ts +121 -0
  421. package/src/plugins/builtin/crypto-etf-flows/pane.tsx +193 -0
  422. package/src/plugins/builtin/debug/index.tsx +1 -0
  423. package/src/plugins/builtin/dividend-yield/index.tsx +1 -1
  424. package/src/plugins/builtin/docs/index.tsx +1 -1
  425. package/src/plugins/builtin/docs/pane.tsx +2 -2
  426. package/src/plugins/builtin/docs/targets.ts +1 -1
  427. package/src/plugins/builtin/doe/client.ts +5 -1
  428. package/src/plugins/builtin/doe/headless.ts +12 -6
  429. package/src/plugins/builtin/doe/model.ts +43 -6
  430. package/src/plugins/builtin/doe/pane.tsx +18 -11
  431. package/src/plugins/builtin/earnings/board-model.ts +13 -6
  432. package/src/plugins/builtin/earnings/board-table.ts +4 -1
  433. package/src/plugins/builtin/earnings/board.tsx +253 -50
  434. package/src/plugins/builtin/earnings/calendar-model.ts +188 -0
  435. package/src/plugins/builtin/earnings/calendar.tsx +338 -0
  436. package/src/plugins/builtin/earnings/client.ts +4 -3
  437. package/src/plugins/builtin/earnings/headless.ts +53 -15
  438. package/src/plugins/builtin/earnings/history-model.ts +53 -36
  439. package/src/plugins/builtin/earnings/index.tsx +15 -22
  440. package/src/plugins/builtin/earnings/model.ts +17 -12
  441. package/src/plugins/builtin/earnings/scope.ts +89 -0
  442. package/src/plugins/builtin/earnings-calls/calendar.tsx +310 -0
  443. package/src/plugins/builtin/earnings-calls/data.ts +146 -2
  444. package/src/plugins/builtin/earnings-calls/headless.ts +151 -9
  445. package/src/plugins/builtin/earnings-calls/index.tsx +3 -3
  446. package/src/plugins/builtin/earnings-calls/lock-note.ts +1 -1
  447. package/src/plugins/builtin/earnings-calls/pane.tsx +149 -31
  448. package/src/plugins/builtin/earnings-calls/upcoming.ts +195 -0
  449. package/src/plugins/builtin/earnings-ripple/pane.tsx +10 -5
  450. package/src/plugins/builtin/econ/calendar-model.ts +132 -20
  451. package/src/plugins/builtin/econ/detail-view.tsx +48 -10
  452. package/src/plugins/builtin/econ/fred-catalog.ts +23 -6
  453. package/src/plugins/builtin/econ/fred-series-map.ts +4 -0
  454. package/src/plugins/builtin/econ/index.tsx +112 -25
  455. package/src/plugins/builtin/econ/print-watch.ts +2 -1
  456. package/src/plugins/builtin/econ/types.ts +32 -1
  457. package/src/plugins/builtin/econ-statistics/client.ts +16 -3
  458. package/src/plugins/builtin/econ-statistics/defs.ts +4 -0
  459. package/src/plugins/builtin/econ-statistics/detail.tsx +2 -2
  460. package/src/plugins/builtin/econ-statistics/headless.ts +13 -2
  461. package/src/plugins/builtin/econ-statistics/index.tsx +3 -3
  462. package/src/plugins/builtin/econ-statistics/pane.tsx +2 -1
  463. package/src/plugins/builtin/econ-statistics/stats.ts +103 -0
  464. package/src/plugins/builtin/econ-statistics/view.ts +16 -1
  465. package/src/plugins/builtin/equity-screener/client.ts +21 -3
  466. package/src/plugins/builtin/equity-screener/headless.ts +68 -6
  467. package/src/plugins/builtin/equity-screener/live.ts +1 -1
  468. package/src/plugins/builtin/equity-screener/model.ts +6 -0
  469. package/src/plugins/builtin/equity-screener/pane.tsx +45 -10
  470. package/src/plugins/builtin/equity-screener/screen-check.ts +90 -0
  471. package/src/plugins/builtin/equity-screener/ticker-check.tsx +148 -0
  472. package/src/plugins/builtin/estimate-revisions/headless.ts +3 -1
  473. package/src/plugins/builtin/estimate-revisions/lock-note.ts +3 -3
  474. package/src/plugins/builtin/estimate-revisions/model.ts +8 -10
  475. package/src/plugins/builtin/exposure/headless.ts +51 -6
  476. package/src/plugins/builtin/exposure/index.tsx +28 -2
  477. package/src/plugins/builtin/exposure/model.ts +7 -0
  478. package/src/plugins/builtin/exposure/pane.tsx +6 -1
  479. package/src/plugins/builtin/fear-greed/index.tsx +1 -1
  480. package/src/plugins/builtin/filing-events/index.tsx +1 -1
  481. package/src/plugins/builtin/futures/model.ts +10 -9
  482. package/src/plugins/builtin/futures/returns.ts +8 -36
  483. package/src/plugins/builtin/futures/table.tsx +1 -1
  484. package/src/plugins/builtin/futures-curve/client.ts +40 -9
  485. package/src/plugins/builtin/futures-curve/headless.ts +39 -17
  486. package/src/plugins/builtin/futures-curve/model.ts +258 -69
  487. package/src/plugins/builtin/futures-curve/pane.tsx +46 -17
  488. package/src/plugins/builtin/fx-matrix/client.ts +15 -8
  489. package/src/plugins/builtin/fx-matrix/headless.ts +32 -14
  490. package/src/plugins/builtin/fx-matrix/index.tsx +13 -11
  491. package/src/plugins/builtin/fx-matrix/live-legs.ts +22 -0
  492. package/src/plugins/builtin/fx-matrix/settings.ts +2 -1
  493. package/src/plugins/builtin/gpu/headless.ts +9 -4
  494. package/src/plugins/builtin/help/index.tsx +13 -3
  495. package/src/plugins/builtin/holders/beneficial-model.ts +8 -11
  496. package/src/plugins/builtin/holders/beneficial-report.ts +6 -5
  497. package/src/plugins/builtin/holders/beneficial-view.tsx +7 -3
  498. package/src/plugins/builtin/holders/client.ts +13 -1
  499. package/src/plugins/builtin/holders/format.ts +28 -17
  500. package/src/plugins/builtin/holders/headless.ts +46 -7
  501. package/src/plugins/builtin/holders/index-holders.ts +264 -0
  502. package/src/plugins/builtin/holders/pane.tsx +79 -15
  503. package/src/plugins/builtin/holders/report-rows.ts +35 -7
  504. package/src/plugins/builtin/holders/table-model.ts +2 -1
  505. package/src/plugins/builtin/holders/treemap.tsx +2 -2
  506. package/src/plugins/builtin/insider/headless.ts +1 -1
  507. package/src/plugins/builtin/insider/signals-client.ts +1 -1
  508. package/src/plugins/builtin/insider/signals.tsx +1 -1
  509. package/src/plugins/builtin/ipo-calendar/pane.tsx +7 -4
  510. package/src/plugins/builtin/iv-history/client.ts +20 -0
  511. package/src/plugins/builtin/iv-history/headless.ts +4 -4
  512. package/src/plugins/builtin/iv-history/index.tsx +1 -1
  513. package/src/plugins/builtin/iv-history/model.ts +13 -4
  514. package/src/plugins/builtin/iv-history/series.ts +3 -1
  515. package/src/plugins/builtin/jobs/lock-note.ts +1 -1
  516. package/src/plugins/builtin/jobs/model.ts +4 -15
  517. package/src/plugins/builtin/jobs/pane.tsx +7 -5
  518. package/src/plugins/builtin/jobs/share-bars.tsx +11 -5
  519. package/src/plugins/builtin/jodi/pane.tsx +10 -4
  520. package/src/plugins/builtin/layout-manager/index.tsx +1 -0
  521. package/src/plugins/builtin/macro-day/headless.ts +20 -7
  522. package/src/plugins/builtin/macro-day/index.tsx +3 -2
  523. package/src/plugins/builtin/macro-day/model.ts +29 -8
  524. package/src/plugins/builtin/macro-day/pane.tsx +46 -10
  525. package/src/plugins/builtin/macro-day/releases.ts +55 -13
  526. package/src/plugins/builtin/market-heatmap/data.ts +9 -2
  527. package/src/plugins/builtin/market-heatmap/evidence.ts +1 -1
  528. package/src/plugins/builtin/market-heatmap/headless.ts +9 -6
  529. package/src/plugins/builtin/market-heatmap/index.tsx +3 -3
  530. package/src/plugins/builtin/market-heatmap/model.ts +10 -7
  531. package/src/plugins/builtin/market-movers/client.ts +33 -19
  532. package/src/plugins/builtin/market-movers/headless.ts +8 -2
  533. package/src/plugins/builtin/market-movers/index.tsx +16 -10
  534. package/src/plugins/builtin/market-movers/screener.ts +29 -8
  535. package/src/plugins/builtin/market-movers/session-body.tsx +4 -2
  536. package/src/plugins/builtin/market-movers/session-table.ts +4 -2
  537. package/src/plugins/builtin/market-movers/table.ts +4 -1
  538. package/src/plugins/builtin/market-valuation/headless.ts +2 -0
  539. package/src/plugins/builtin/market-valuation/view.ts +5 -0
  540. package/src/plugins/builtin/members/headless.ts +6 -5
  541. package/src/plugins/builtin/members/pane.tsx +11 -4
  542. package/src/plugins/builtin/mna/client.ts +1 -0
  543. package/src/plugins/builtin/mna/detail.tsx +20 -32
  544. package/src/plugins/builtin/mna/distress/detail.tsx +16 -4
  545. package/src/plugins/builtin/mna/distress/model.ts +3 -2
  546. package/src/plugins/builtin/mna/distress/pane.tsx +7 -4
  547. package/src/plugins/builtin/mna/headless.ts +6 -13
  548. package/src/plugins/builtin/mna/model.ts +93 -15
  549. package/src/plugins/builtin/mna/pane.tsx +5 -4
  550. package/src/plugins/builtin/news/headless.ts +12 -6
  551. package/src/plugins/builtin/news/index.tsx +10 -1
  552. package/src/plugins/builtin/news/wire/index.tsx +3 -2
  553. package/src/plugins/builtin/news/wire/news/command-bar-search.ts +26 -10
  554. package/src/plugins/builtin/news/wire/news/query-presets.ts +6 -2
  555. package/src/plugins/builtin/news/wire/rss/cli.ts +3 -3
  556. package/src/plugins/builtin/notes/cli.ts +49 -14
  557. package/src/plugins/builtin/openfda/pane.tsx +1 -1
  558. package/src/plugins/builtin/options/carry.ts +2 -2
  559. package/src/plugins/builtin/options/index.tsx +1 -1
  560. package/src/plugins/builtin/options/view.tsx +10 -10
  561. package/src/plugins/builtin/options-calculator/headless.ts +46 -7
  562. package/src/plugins/builtin/options-scenario/client.ts +123 -28
  563. package/src/plugins/builtin/options-scenario/collar.ts +8 -6
  564. package/src/plugins/builtin/options-scenario/csp-screen-headless.ts +127 -0
  565. package/src/plugins/builtin/options-scenario/csp-screen-pane.tsx +165 -0
  566. package/src/plugins/builtin/options-scenario/csp-screen.ts +258 -0
  567. package/src/plugins/builtin/options-scenario/csp.ts +101 -21
  568. package/src/plugins/builtin/options-scenario/headless.ts +36 -15
  569. package/src/plugins/builtin/options-scenario/hedge.ts +20 -14
  570. package/src/plugins/builtin/options-scenario/index.tsx +28 -3
  571. package/src/plugins/builtin/options-scenario/model.ts +13 -0
  572. package/src/plugins/builtin/options-scenario/pane.tsx +9 -5
  573. package/src/plugins/builtin/perps/equity-row.tsx +11 -3
  574. package/src/plugins/builtin/perps/freshness.ts +8 -5
  575. package/src/plugins/builtin/perps/headless.ts +3 -1
  576. package/src/plugins/builtin/perps/list-perpetuals.ts +25 -4
  577. package/src/plugins/builtin/perps/live-rows.ts +161 -0
  578. package/src/plugins/builtin/perps/markets-section.tsx +154 -0
  579. package/src/plugins/builtin/perps/pane.tsx +36 -17
  580. package/src/plugins/builtin/perps/venue-markets.ts +96 -0
  581. package/src/plugins/builtin/plugin-marketplace/index.tsx +2 -1
  582. package/src/plugins/builtin/plugin-marketplace/pane.tsx +143 -59
  583. package/src/plugins/builtin/portfolio-list/cli/bulk-symbols.ts +72 -24
  584. package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +158 -141
  585. package/src/plugins/builtin/portfolio-list/cli/render.ts +49 -20
  586. package/src/plugins/builtin/portfolio-list/cli/shared.ts +3 -3
  587. package/src/plugins/builtin/portfolio-list/cli/watchlist-command.ts +29 -24
  588. package/src/plugins/builtin/portfolio-list/headless.ts +6 -3
  589. package/src/plugins/builtin/portfolio-list/income.ts +13 -2
  590. package/src/plugins/builtin/portfolio-list/index.tsx +9 -2
  591. package/src/plugins/builtin/portfolio-list/pane/index.tsx +21 -8
  592. package/src/plugins/builtin/portfolio-list/pane/purchase-date-fx.ts +46 -0
  593. package/src/plugins/builtin/portfolio-list/summary/live-accounts.ts +16 -9
  594. package/src/plugins/builtin/portfolio-list/summary/totals.ts +2 -15
  595. package/src/plugins/builtin/power/client.ts +4 -1
  596. package/src/plugins/builtin/power/evidence.ts +22 -7
  597. package/src/plugins/builtin/power/gas.tsx +5 -1
  598. package/src/plugins/builtin/power/pane.tsx +8 -1
  599. package/src/plugins/builtin/power/prices.tsx +10 -3
  600. package/src/plugins/builtin/research/analyst-headless.ts +25 -8
  601. package/src/plugins/builtin/research/analyst-model.ts +68 -3
  602. package/src/plugins/builtin/research/corporate-actions-pane.tsx +63 -14
  603. package/src/plugins/builtin/research/event-model.ts +3 -1
  604. package/src/plugins/builtin/research/event-sources.ts +12 -4
  605. package/src/plugins/builtin/research/index.tsx +2 -1
  606. package/src/plugins/builtin/research/relative-valuation-basis.ts +58 -0
  607. package/src/plugins/builtin/research/relative-valuation-columns.ts +31 -2
  608. package/src/plugins/builtin/research/relative-valuation-currency.ts +12 -5
  609. package/src/plugins/builtin/research/relative-valuation-headless.ts +84 -26
  610. package/src/plugins/builtin/research/relative-valuation-model.ts +88 -19
  611. package/src/plugins/builtin/research/relative-valuation-pane.tsx +76 -9
  612. package/src/plugins/builtin/research/relative-valuation-peers.ts +1 -1
  613. package/src/plugins/builtin/reverse-dcf/model.ts +6 -2
  614. package/src/plugins/builtin/risk-factors/index.tsx +2 -2
  615. package/src/plugins/builtin/scanner/lock-note.ts +1 -1
  616. package/src/plugins/builtin/sec/forms.ts +13 -0
  617. package/src/plugins/builtin/sec/fund-abroad.ts +32 -0
  618. package/src/plugins/builtin/sec/fund-facts.ts +68 -8
  619. package/src/plugins/builtin/sec/headless.ts +85 -8
  620. package/src/plugins/builtin/sec/index.tsx +58 -12
  621. package/src/plugins/builtin/sectors/client.ts +2 -1
  622. package/src/plugins/builtin/sectors/sector-model.ts +11 -15
  623. package/src/plugins/builtin/series-inventory.ts +2 -0
  624. package/src/plugins/builtin/shared/broker-reconnect.ts +107 -22
  625. package/src/plugins/builtin/shared/cloud-upgrade.ts +34 -6
  626. package/src/plugins/builtin/shared/earnings-calendar.ts +375 -0
  627. package/src/plugins/builtin/{earnings/estimate-basis.ts → shared/earnings-estimate-basis.ts} +1 -1
  628. package/src/plugins/builtin/shared/earnings-report.ts +3 -3
  629. package/src/plugins/builtin/shared/fx-rate-freshness.ts +23 -1
  630. package/src/plugins/builtin/shared/job-posting.ts +129 -0
  631. package/src/plugins/builtin/shared/pro-lock-note.ts +3 -3
  632. package/src/plugins/builtin/shared/report-freshness.ts +3 -0
  633. package/src/plugins/builtin/shared/research-trading.tsx +21 -0
  634. package/src/plugins/builtin/shared/series-cache.ts +2 -0
  635. package/src/plugins/builtin/shared/ticker-surface.ts +2 -1
  636. package/src/plugins/builtin/short-interest/client.ts +2 -0
  637. package/src/plugins/builtin/short-interest/headless.ts +41 -12
  638. package/src/plugins/builtin/short-interest/index.tsx +23 -1
  639. package/src/plugins/builtin/short-interest/model.ts +70 -19
  640. package/src/plugins/builtin/short-interest/pane.tsx +19 -2
  641. package/src/plugins/builtin/short-interest/publications-client.ts +82 -0
  642. package/src/plugins/builtin/short-interest/publications-headless.ts +29 -0
  643. package/src/plugins/builtin/short-interest/publications-model.ts +50 -0
  644. package/src/plugins/builtin/short-interest/publications-pane.tsx +66 -0
  645. package/src/plugins/builtin/short-interest/schedule.ts +35 -2
  646. package/src/plugins/builtin/short-interest/surface.tsx +11 -4
  647. package/src/plugins/builtin/short-interest/types.ts +9 -0
  648. package/src/plugins/builtin/short-interest/watch-client.ts +14 -8
  649. package/src/plugins/builtin/short-interest/watch-model.ts +12 -25
  650. package/src/plugins/builtin/short-interest/watch-pane.tsx +5 -1
  651. package/src/plugins/builtin/supply-chain/flow.tsx +33 -9
  652. package/src/plugins/builtin/supply-chain/model.ts +51 -3
  653. package/src/plugins/builtin/supply-chain/pane.tsx +78 -39
  654. package/src/plugins/builtin/supply-chain/row-evidence.tsx +1 -1
  655. package/src/plugins/builtin/themes/headless.ts +8 -5
  656. package/src/plugins/builtin/themes/model.ts +14 -4
  657. package/src/plugins/builtin/themes/pane.tsx +24 -5
  658. package/src/plugins/builtin/thirteenf/headless.ts +5 -5
  659. package/src/plugins/builtin/thirteenf/signals.ts +3 -1
  660. package/src/plugins/builtin/ticker-detail/adr-pair/headless.ts +123 -0
  661. package/src/plugins/builtin/ticker-detail/adr-pair/model.ts +132 -0
  662. package/src/plugins/builtin/ticker-detail/adr-pair/tab.tsx +87 -0
  663. package/src/plugins/builtin/ticker-detail/data-panes/historical-prices.tsx +40 -26
  664. package/src/plugins/builtin/ticker-detail/data-panes/history-bars.ts +8 -4
  665. package/src/plugins/builtin/ticker-detail/data-panes/returns-history.ts +67 -3
  666. package/src/plugins/builtin/ticker-detail/data-panes/returns-model.ts +112 -5
  667. package/src/plugins/builtin/ticker-detail/data-panes/returns-pane.tsx +17 -2
  668. package/src/plugins/builtin/ticker-detail/financials/aggregation.ts +21 -7
  669. package/src/plugins/builtin/ticker-detail/financials/model.ts +36 -1
  670. package/src/plugins/builtin/ticker-detail/financials/offerings.ts +56 -0
  671. package/src/plugins/builtin/ticker-detail/financials/ratios.ts +62 -13
  672. package/src/plugins/builtin/ticker-detail/financials/tab.tsx +30 -4
  673. package/src/plugins/builtin/ticker-detail/headless-schema.ts +14 -2
  674. package/src/plugins/builtin/ticker-detail/headless.ts +148 -35
  675. package/src/plugins/builtin/ticker-detail/index.tsx +37 -5
  676. package/src/plugins/builtin/ticker-detail/overview/model.ts +65 -10
  677. package/src/plugins/builtin/ticker-detail/overview/pane.tsx +9 -1
  678. package/src/plugins/builtin/ticker-detail/overview-tab.tsx +68 -11
  679. package/src/plugins/builtin/ticker-detail/pane.tsx +11 -0
  680. package/src/plugins/builtin/ticker-detail/quote-footer.ts +8 -3
  681. package/src/plugins/builtin/ticker-detail/research-tabs.ts +11 -0
  682. package/src/plugins/builtin/vol-surface/client.ts +5 -4
  683. package/src/plugins/builtin/vol-surface/headless.ts +12 -3
  684. package/src/plugins/builtin/vol-surface/model.ts +4 -2
  685. package/src/plugins/builtin/volatility/model.ts +5 -10
  686. package/src/plugins/builtin/world-venue-map/basemap-layer.tsx +4 -3
  687. package/src/plugins/builtin/world-venue-map/basemap.ts +3 -1
  688. package/src/plugins/builtin/world-venue-map/chokepoint-chart.ts +40 -0
  689. package/src/plugins/builtin/world-venue-map/evidence.ts +1 -1
  690. package/src/plugins/builtin/world-venue-map/geo-series.ts +90 -11
  691. package/src/plugins/builtin/world-venue-map/headless.ts +1 -1
  692. package/src/plugins/builtin/world-venue-map/index.ts +3 -26
  693. package/src/plugins/builtin/world-venue-map/layers.ts +1 -1
  694. package/src/plugins/builtin/world-venue-map/map.tsx +2 -1
  695. package/src/plugins/builtin/world-venue-map/pane.tsx +4 -2
  696. package/src/plugins/builtin/world-venue-map/venue-header.tsx +15 -4
  697. package/src/plugins/builtin/yield-curve/client.ts +25 -0
  698. package/src/plugins/builtin/yield-curve/curves.ts +7 -4
  699. package/src/plugins/builtin/yield-curve/headless.ts +38 -4
  700. package/src/plugins/builtin/yield-curve/history.ts +4 -3
  701. package/src/plugins/builtin/yield-curve/index.tsx +12 -6
  702. package/src/plugins/builtin/yield-curve/swaps-model.ts +93 -0
  703. package/src/plugins/builtin/yield-curve/swaps.tsx +99 -0
  704. package/src/plugins/bundle.ts +1 -1
  705. package/src/plugins/catalog-browser.ts +2 -1
  706. package/src/plugins/compat.ts +3 -3
  707. package/src/plugins/dependencies.ts +75 -14
  708. package/src/plugins/extracted-plugins.ts +132 -34
  709. package/src/plugins/host-link.ts +149 -34
  710. package/src/plugins/installer.ts +35 -10
  711. package/src/plugins/loader.ts +206 -38
  712. package/src/plugins/manager-node.ts +2 -2
  713. package/src/plugins/marketplace/deactivation.ts +22 -0
  714. package/src/plugins/marketplace/model.ts +2 -2
  715. package/src/plugins/marketplace/packs.ts +1 -1
  716. package/src/plugins/ownership.ts +1 -1
  717. package/src/plugins/peer-retry.ts +155 -0
  718. package/src/plugins/registry/contributions.ts +3 -1
  719. package/src/plugins/registry/index.ts +4 -3
  720. package/src/plugins/registry/plugin-state.ts +3 -0
  721. package/src/plugins/seed-notice.ts +20 -0
  722. package/src/plugins/shortcut-argument.ts +39 -0
  723. package/src/portfolio/allocation.ts +1 -1
  724. package/src/portfolio/collection-name.ts +31 -0
  725. package/src/portfolio/column-values.ts +10 -8
  726. package/src/portfolio/cost-fx.ts +296 -19
  727. package/src/portfolio/manual-lots.ts +75 -0
  728. package/src/portfolio/mutations.ts +60 -22
  729. package/src/portfolio/suffixed-listings.ts +209 -0
  730. package/src/portfolio/totals-currency.ts +24 -0
  731. package/src/public/__snapshots__/public-api.test.ts.snap +14 -0
  732. package/src/public/time-series.ts +11 -8
  733. package/src/remote/schema.ts +1 -1
  734. package/src/renderers/browser/config-host.ts +3 -0
  735. package/src/renderers/browser/main.tsx +23 -3
  736. package/src/renderers/dom/boot-frame-page.ts +187 -0
  737. package/src/renderers/dom/boot-frame.ts +237 -0
  738. package/src/renderers/dom/build-assets.ts +46 -8
  739. package/src/renderers/dom/dom-ui-host.tsx +4 -29
  740. package/src/renderers/dom/host/ascii-text.ts +16 -2
  741. package/src/renderers/dom/host/box.tsx +43 -2
  742. package/src/renderers/dom/host/chart-surface.tsx +2 -0
  743. package/src/renderers/dom/host/hls.chunk.ts +3 -0
  744. package/src/renderers/dom/host/image-surface.tsx +49 -0
  745. package/src/renderers/dom/host/media-surface.tsx +24 -18
  746. package/src/renderers/dom/host/mouse.ts +30 -0
  747. package/src/renderers/dom/host/size-observer.ts +1 -1
  748. package/src/renderers/dom/host/style.ts +1 -1
  749. package/src/renderers/dom/styles.css +76 -0
  750. package/src/renderers/dom/test-utils.tsx +2 -1
  751. package/src/renderers/electrobun/bun/application-menu/index.ts +3 -3
  752. package/src/renderers/electrobun/bun/desktop/backend-requests.ts +3 -0
  753. package/src/renderers/electrobun/bun/desktop/backend.ts +46 -3
  754. package/src/renderers/electrobun/bun/desktop/detached-windows.ts +1 -1
  755. package/src/renderers/electrobun/bun/desktop/host-requests.ts +9 -3
  756. package/src/renderers/electrobun/bun/desktop/initialization.ts +81 -18
  757. package/src/renderers/electrobun/bun/external-plugins.ts +29 -7
  758. package/src/renderers/electrobun/bun/index.ts +11 -1
  759. package/src/renderers/electrobun/bun/window/boot-frame.ts +67 -0
  760. package/src/renderers/electrobun/bun/window/create.ts +4 -1
  761. package/src/renderers/electrobun/shared/boot-frame.ts +7 -0
  762. package/src/renderers/electrobun/shared/protocol.ts +6 -1
  763. package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +1 -1
  764. package/src/renderers/electrobun/view/config-host.ts +3 -0
  765. package/src/renderers/electrobun/view/fatal-screen.tsx +1 -1
  766. package/src/renderers/electrobun/view/main.tsx +30 -4
  767. package/src/renderers/electrobun/view/news-source.ts +5 -5
  768. package/src/renderers/electrobun/view/remote/asset-data-client.ts +1 -1
  769. package/src/renderers/electrobun/view/ui-host.tsx +1 -1
  770. package/src/renderers/opentui/browser-open.ts +88 -0
  771. package/src/renderers/opentui/host.tsx +5 -14
  772. package/src/renderers/opentui/image/loader.ts +3 -2
  773. package/src/renderers/opentui/native-smoke.ts +10 -1
  774. package/src/renderers/opentui/pane-image/index.ts +2 -1
  775. package/src/renderers/opentui/render-lib.ts +253 -0
  776. package/src/renderers/opentui/render-timing-smoke.ts +1 -1
  777. package/src/renderers/opentui/start.tsx +1 -1
  778. package/src/renderers/share/layout-view.tsx +2 -2
  779. package/src/renderers/share/main.tsx +4 -4
  780. package/src/renderers/share/view.tsx +1 -1
  781. package/src/series/resolve.ts +22 -6
  782. package/src/series/standalone.ts +30 -2
  783. package/src/series/types.ts +8 -1
  784. package/src/shares/api.ts +4 -1
  785. package/src/shares/pane.ts +1 -1
  786. package/src/sources/gloomberb-cloud/fred-series.ts +46 -1
  787. package/src/sources/gloomberb-cloud/index.ts +32 -16
  788. package/src/sources/gloomberb-cloud/news.ts +39 -0
  789. package/src/sources/gloomberb-cloud/normalizers.ts +14 -1
  790. package/src/sources/gloomberb-cloud/perpetuals.ts +49 -1
  791. package/src/sources/listing-symbols.ts +37 -0
  792. package/src/sources/provider-errors.ts +16 -2
  793. package/src/sources/provider-router/financial-routes.ts +21 -3
  794. package/src/sources/provider-router/financials.ts +15 -2
  795. package/src/sources/provider-router/history.ts +30 -8
  796. package/src/sources/provider-router/primary.ts +1 -1
  797. package/src/state/app/bootstrap.ts +23 -0
  798. package/src/state/hooks/inline-tickers.ts +30 -5
  799. package/src/sync/controller.ts +1 -1
  800. package/src/sync/core-contributors.ts +46 -14
  801. package/src/team/collections-sync.ts +2 -1
  802. package/src/team/collections.ts +178 -17
  803. package/src/telemetry/crash-reports.ts +17 -4
  804. package/src/test-support/builtin-panes.ts +1 -1
  805. package/src/theme/colors.ts +3 -30
  806. package/src/theme/ui-tokens.ts +37 -1
  807. package/src/tickers/company-name-listing.ts +210 -33
  808. package/src/tickers/index-roots.ts +47 -0
  809. package/src/tickers/instrument-label.ts +5 -1
  810. package/src/tickers/metadata.ts +10 -0
  811. package/src/tickers/perpetual-listing.ts +5 -2
  812. package/src/tickers/search/home-listing.ts +75 -0
  813. package/src/tickers/search/index.ts +76 -27
  814. package/src/tickers/search/ranking.ts +54 -4
  815. package/src/tickers/search/upsert.ts +29 -0
  816. package/src/tickers/terminal-codes.ts +416 -40
  817. package/src/time-series/bar-aggregation.ts +243 -0
  818. package/src/time-series/base-series.ts +307 -0
  819. package/src/time-series/chart-bounds.ts +349 -0
  820. package/src/time-series/chart-seed.ts +142 -0
  821. package/src/time-series/economic.ts +5 -0
  822. package/src/time-series/fundamentals.ts +18 -3
  823. package/src/time-series/history-acquisition.ts +499 -0
  824. package/src/time-series/leverage.ts +100 -0
  825. package/src/time-series/market-resolution.ts +4 -2
  826. package/src/time-series/market.ts +2 -1
  827. package/src/time-series/price-comparison.ts +175 -30
  828. package/src/time-series/range.ts +9 -1
  829. package/src/time-series/resolution.ts +174 -16
  830. package/src/time-series/resolve-context.ts +157 -0
  831. package/src/time-series/resolve.ts +126 -1577
  832. package/src/time-series/series-name.ts +38 -0
  833. package/src/time-series/series-presentation.ts +208 -0
  834. package/src/time-series/spec.ts +11 -6
  835. package/src/time-series/studies.ts +109 -12
  836. package/src/time-series/tail-reconcile.ts +121 -0
  837. package/src/time-series/types.ts +29 -2
  838. package/src/time-series/use-chart-resolution.ts +4 -5
  839. package/src/types/broker.ts +10 -0
  840. package/src/types/config.ts +14 -0
  841. package/src/types/data-provider.ts +14 -0
  842. package/src/types/exchange-rate.ts +6 -0
  843. package/src/types/financials.ts +104 -7
  844. package/src/types/headless.ts +76 -6
  845. package/src/types/instrument.ts +3 -0
  846. package/src/types/plugin.ts +65 -8
  847. package/src/types/price-history.ts +2 -0
  848. package/src/types/ticker.ts +13 -0
  849. package/src/types/trading.ts +59 -1
  850. package/src/ui/ascii-font.ts +13 -1
  851. package/src/ui/host.tsx +6 -1
  852. package/src/updater/command-names.ts +175 -0
  853. package/src/updater/index.ts +10 -5
  854. package/src/utils/calendar-date.ts +32 -15
  855. package/src/utils/cash-runway.ts +241 -0
  856. package/src/utils/central-banks.ts +42 -0
  857. package/src/utils/cli-output.ts +259 -80
  858. package/src/utils/contract-month.ts +16 -0
  859. package/src/utils/crypto-pair.ts +61 -3
  860. package/src/utils/currency-units.ts +29 -0
  861. package/src/utils/datetime-format.ts +10 -0
  862. package/src/utils/debug-log.ts +1 -1
  863. package/src/utils/decimal-comma.ts +39 -6
  864. package/src/utils/exchange-announcements.ts +71 -0
  865. package/src/utils/exchange-rate-snapshot.ts +10 -0
  866. package/src/utils/financial-statements.ts +83 -4
  867. package/src/utils/format.ts +34 -16
  868. package/src/utils/fundamentals.ts +150 -34
  869. package/src/utils/fx-market-hours.ts +10 -1
  870. package/src/utils/latest-financial-period.ts +8 -0
  871. package/src/utils/linux-libc.ts +54 -0
  872. package/src/utils/market-capitalization.ts +111 -15
  873. package/src/utils/max-drawdown.ts +64 -0
  874. package/src/utils/network-failure.ts +83 -0
  875. package/src/utils/option-expiry.ts +139 -7
  876. package/src/utils/price-earnings.ts +11 -5
  877. package/src/utils/price-history.ts +18 -8
  878. package/src/utils/price-window.ts +131 -0
  879. package/src/utils/release-date.ts +47 -0
  880. package/src/utils/sec.ts +3 -0
  881. package/src/utils/throttled-fetch.ts +11 -4
  882. package/src/utils/trailing-eps.ts +67 -0
  883. package/src/utils/typed-text.ts +21 -0
  884. package/src/utils/utc-time.ts +24 -1
  885. package/src/version.ts +6 -0
  886. package/src/cli/pane-functions/screenshot.ts +0 -2122
@@ -1,13 +1,13 @@
1
1
  /**
2
- * `gloomberb fn ALRT`: the Alerts pane's three tabs as reports. Prices lists
2
+ * `gloom fn ALRT`: the Alerts pane's three tabs as reports. Prices lists
3
3
  * the price alerts as the pane's table does, Events the event alerts (earnings,
4
- * CPI and FOMC with their dates, filings, news, market moves), History the
5
- * alerts delivered to the account over the last 90 days.
4
+ * CPI, FOMC and other calendar releases with their dates, filings, news, IV levels, market moves),
5
+ * History the alerts this device's app fired, with the ones Gloom Cloud
6
+ * delivered to the account over the last 90 days when signed in.
6
7
  */
7
8
  import type { HeadlessPaneColumn, HeadlessPaneContext, HeadlessPaneDefinition, HeadlessPaneRow, HeadlessRowsResult } from "../../../types/headless";
8
9
  import type { PaneLock } from "../../../types/plugin";
9
- import { newYorkToday } from "../earnings/board-model";
10
- import { explainRefusal } from "../shared/cloud-denied";
10
+ import { refusedLock } from "../shared/cloud-denied";
11
11
  import { ALERT_TABS, ALERTS_PLUGIN_ID } from "./constants";
12
12
  import { ruleState } from "./event-rows";
13
13
  import { eventAlertTarget, type EventAlertRule } from "./events";
@@ -19,7 +19,10 @@ import {
19
19
  formatQuoteChecked,
20
20
  relativeTime,
21
21
  } from "./format";
22
+ import { FIRED_LOG_KEY, firedAlertTime, quoteSourceWords, readFiredAlerts } from "./fired-log";
22
23
  import { alertKindLabel, validateAlertHistory, type AlertHistory, type AlertHistoryItem } from "./history";
24
+ import { ALERT_HISTORY_VIA, mergeAlertHistory, type AlertHistoryRow } from "./history-rows";
25
+ import { IV_LEVEL_CHECKS_KEY, ivLevelCheckText, readIvLevelChecks, type IvLevelCheck } from "./iv-level";
23
26
  import { readScheduledRule, scheduledEventName } from "./scheduled";
24
27
  import { readAlertStores } from "./storage";
25
28
  import type { AlertRule } from "./types";
@@ -33,40 +36,71 @@ const plural = (count: number, word: string) => `${count} ${word}${count === 1 ?
33
36
  const asAlert = (row: HeadlessPaneRow) => row as unknown as AlertRule;
34
37
  const text = (value: unknown) => (typeof value === "string" && value ? value : "");
35
38
 
36
- /** The text report words each cell as the pane does; CSV and JSON keep the stored numbers and times. */
39
+ const percent = (value: unknown) => (typeof value === "number" && Number.isFinite(value) ? `${value.toFixed(1)}%` : "");
40
+ const instant = (value: unknown) => (typeof value === "number" ? firedAlertTime(value) ?? "" : "");
41
+
42
+ /**
43
+ * The text report words each cell as the pane does: the quote's age and feed, the distance signed.
44
+ * CSV and JSON keep the stored numbers, with Away in %, and the quote's own time and feed in Quote
45
+ * and Quote source, apart from when the app last checked the alert.
46
+ */
37
47
  const PRICE_COLUMNS: HeadlessPaneColumn[] = [
38
48
  { key: "status", header: "State", format: (value) => (value === "triggered" ? "Triggered" : "Active") },
39
49
  { key: "symbol", header: "Symbol", format: (value, row) => (row.exchange ? `${text(value)}:${text(row.exchange)}` : text(value)) },
40
50
  { key: "lastCheckedPrice", header: "Current", align: "right", textFormat: (_value, row) => formatCurrentPrice(asAlert(row), 14) },
41
51
  { key: "targetPrice", header: "Target", align: "right", textFormat: (_value, row) => formatAlertTargetPrice(asAlert(row), 14) },
42
- { key: "awayPercent", header: "Away", align: "right", textFormat: (_value, row) => formatAlertDistance(asAlert(row)) },
52
+ { key: "awayPercent", header: "Away", align: "right", format: percent, textFormat: (_value, row) => formatAlertDistance(asAlert(row)) },
43
53
  { key: "condition", header: "Trigger", format: (value) => conditionLabel(value as AlertRule["condition"]) },
44
- { key: "lastCheckedAt", header: "Quote", textFormat: (_value, row) => formatQuoteChecked(asAlert(row)) },
45
- { key: "triggeredAt", header: "Alerted", textFormat: (value) => (typeof value === "number" ? relativeTime(value) : "-") },
54
+ { key: "quoteAt", header: "Quote", textFormat: (_value, row) => formatQuoteChecked(asAlert(row)) },
55
+ { key: "quoteSource", header: "Quote source" },
56
+ { key: "lastCheckedAt", header: "Checked", format: instant },
57
+ { key: "triggeredAt", header: "Alerted", format: instant, textFormat: (value) => (typeof value === "number" ? relativeTime(value) : "-") },
46
58
  ];
59
+ /** The terminal table keeps the pane's columns: the Quote cell already says the quote's age and feed. */
60
+ const PRICE_TEXT_COLUMNS = PRICE_COLUMNS.filter((column) => column.key !== "quoteSource" && column.key !== "lastCheckedAt");
47
61
 
48
62
  const EVENT_COLUMNS: HeadlessPaneColumn[] = [
49
63
  { key: "event", header: "Event" },
50
64
  { key: "following", header: "Following" },
51
65
  { key: "eventDate", header: "Event date", textFormat: (value, row) => text(value) || (row.leadDays == null ? "" : "not known yet") },
52
- { key: "leadDays", header: "Days before", align: "right" },
66
+ // A results alert waits for the report instead of a lead time.
67
+ { key: "leadDays", header: "Days before", align: "right", textFormat: (value, row) => (row.when === "results" ? "results" : value == null ? "-" : String(value)) },
53
68
  { key: "state", header: "State" },
54
69
  { key: "since", header: "Since" },
55
70
  ];
56
71
 
72
+ const minute = (value: unknown) => text(value).slice(0, 16).replace("T", " ");
73
+ const valueText = (value: unknown, row: HeadlessPaneRow) => (typeof value === "number" && Number.isFinite(value)
74
+ ? `${Number(value.toFixed(4))}${row.unit === "%" ? "%" : row.unit ? ` ${text(row.unit)}` : ""}` : "");
75
+
76
+ /**
77
+ * One line per alert, the app's and Gloom Cloud's together, newest first: when it went off, what
78
+ * sent it, the rule, the figure in its unit, and the quote behind it with its own time and feed.
79
+ */
57
80
  const HISTORY_COLUMNS: HeadlessPaneColumn[] = [
58
- { key: "deliveredAt", header: "Sent (UTC)", format: (value) => text(value).slice(0, 16).replace("T", " ") },
81
+ { key: "time", header: "Time (UTC)", format: minute },
82
+ { key: "via", header: "Via" },
59
83
  { key: "event", header: "Event" },
60
- { key: "title", header: "Alert" },
61
- { key: "body", header: "Detail" },
84
+ { key: "alert", header: "Alert" },
85
+ { key: "value", header: "Value", align: "right", unitKey: "unit", textFormat: valueText },
86
+ { key: "quoteAt", header: "Quote time (UTC)", format: minute },
87
+ { key: "quoteSource", header: "Quote source" },
88
+ { key: "detail", header: "Detail", shrink: true },
62
89
  ];
90
+ const HISTORY_TEXT_COLUMNS = HISTORY_COLUMNS.filter((column) => column.key !== "via");
63
91
 
64
- /** A price alert as the Prices table lists it: the stored fields, without the quote's provider id, and the distance to target. */
92
+ /** A price alert as the Prices table lists it: the stored fields, without the quote's provider id, the distance to target, and its quote's own time and feed. */
65
93
  function priceRow(alert: AlertRule): HeadlessPaneRow {
66
94
  const { lastQuoteProviderId: _provider, ...stored } = alert;
67
95
  const price = alert.lastCheckError ? null : alert.lastCheckedPrice;
68
96
  const away = price == null || !Number.isFinite(price) || price === 0 ? null : ((alert.targetPrice - price) / price) * 100;
69
- return { ...stored, awayPercent: away != null && Number.isFinite(away) ? away : null };
97
+ const quoted = !alert.lastCheckError;
98
+ return {
99
+ ...stored,
100
+ awayPercent: away != null && Number.isFinite(away) ? Number(away.toFixed(2)) : null,
101
+ quoteAt: quoted ? firedAlertTime(alert.lastQuoteUpdatedAt) : null,
102
+ quoteSource: quoted ? quoteSourceWords(alert.lastQuoteSource) : null,
103
+ };
70
104
  }
71
105
 
72
106
  /** Active alerts first, then the ones that went off, latest first, as the pane orders them. */
@@ -75,15 +109,16 @@ function pricesResult(alerts: readonly AlertRule[], error: string | null, events
75
109
  const triggered = alerts.filter((alert) => alert.status === "triggered").sort((a, b) => (b.triggeredAt ?? 0) - (a.triggeredAt ?? 0));
76
110
  return {
77
111
  columns: PRICE_COLUMNS,
112
+ textColumns: PRICE_TEXT_COLUMNS,
78
113
  rows: [...active, ...triggered].map(priceRow),
79
- empty: "No price alerts. Add one with gloomberb alerts add AAPL above 250.",
114
+ empty: "No price alerts. Add one with gloom alerts add AAPL above 250.",
80
115
  ...(error ? { errors: [error], complete: false } : {}),
81
- ...(events > 0 ? { notes: [`${plural(events, "event alert")} not listed here: gloomberb fn ALRT --tab events`] } : {}),
116
+ ...(events > 0 ? { notes: [`${plural(events, "event alert")} not listed here: gloom fn ALRT --tab events`] } : {}),
82
117
  };
83
118
  }
84
119
 
85
120
  /** An event alert as the Events table lists it: a scheduled one with its event date and lead time apart. */
86
- function eventRow(rule: EventAlertRule, today: string): HeadlessPaneRow {
121
+ function eventRow(rule: EventAlertRule, now: number, checks: Record<string, IvLevelCheck>): HeadlessPaneRow {
87
122
  const scheduled = readScheduledRule(rule);
88
123
  return {
89
124
  id: rule.id,
@@ -92,40 +127,54 @@ function eventRow(rule: EventAlertRule, today: string): HeadlessPaneRow {
92
127
  following: scheduled ? scheduledEventName(scheduled.target) : eventAlertTarget(rule),
93
128
  eventDate: scheduled ? rule.eventDate ?? null : null,
94
129
  leadDays: scheduled?.leadDays ?? null,
95
- state: ruleState(rule, today),
130
+ ...(scheduled?.trigger === "results" ? { when: "results" } : {}),
131
+ state: ruleState(rule, now),
96
132
  since: new Date(rule.createdAt).toISOString().slice(0, 10),
133
+ // An IV level's last reading, or why there was none, on its own row.
134
+ ...rule.kind === "iv_level" ? { lastCheck: ivLevelCheckText(rule, checks[rule.id]) } : {},
97
135
  };
98
136
  }
99
137
 
100
- function eventsResult(rules: readonly EventAlertRule[], error: string | null): HeadlessRowsResult {
101
- const today = newYorkToday();
138
+ function eventsResult(rules: readonly EventAlertRule[], error: string | null, checks: Record<string, IvLevelCheck>): HeadlessRowsResult {
139
+ const now = Date.now();
140
+ const checked = rules.some((rule) => rule.kind === "iv_level");
102
141
  return {
103
- columns: EVENT_COLUMNS,
104
- rows: [...rules].sort((a, b) => b.createdAt - a.createdAt).map((rule) => eventRow(rule, today)),
105
- empty: "No event alerts. Add one with gloomberb alerts add CRWV earnings --days 3 or gloomberb alerts add CPI --days 1.",
142
+ // A Last check column only when an IV level rule has a reading to show.
143
+ columns: checked ? [...EVENT_COLUMNS.slice(0, -2), { key: "lastCheck", header: "Last check" }, ...EVENT_COLUMNS.slice(-2)] : EVENT_COLUMNS,
144
+ rows: [...rules].sort((a, b) => b.createdAt - a.createdAt).map((rule) => eventRow(rule, now, checks)),
145
+ empty: "No event alerts. Add one with gloom alerts add CRWV earnings --days 3, gloom alerts add CPI --days 1 or gloom alerts add CN PMI.",
106
146
  ...(error ? { errors: [error], complete: false } : {}),
107
147
  };
108
148
  }
109
149
 
110
- function historyRow(item: AlertHistoryItem): HeadlessPaneRow {
111
- return { id: item.id, deliveredAt: item.deliveredAt, kind: item.kind, event: alertKindLabel(item.kind), title: item.title, body: item.body };
150
+ /** One alert that went off: fired by this app, delivered by Gloom Cloud, or both, on one line. */
151
+ function historyRow(row: AlertHistoryRow): HeadlessPaneRow {
152
+ return {
153
+ id: row.fired?.id ?? row.delivered?.id ?? row.id, time: row.time, via: ALERT_HISTORY_VIA[row.via], kind: row.kind,
154
+ event: alertKindLabel(row.kind), alert: row.alert, value: row.value, unit: row.unit, quoteAt: row.quoteAt,
155
+ quoteSource: row.source, detail: row.detail,
156
+ };
112
157
  }
113
158
 
114
- /** What a signed-out read of History says: the tab is the account's own list of delivered alerts. */
159
+ /** What a signed-out read of History adds: only this device's own alerts are listed. */
115
160
  export function alertHistoryLockNote({ verifyEmail }: PaneLock): string {
116
161
  const account = verifyEmail
117
162
  ? "verify your email (Ctrl+P, Resend Verification Email)"
118
163
  : "log in or sign up free from the command bar (Ctrl+P, Log In or Sign Up)";
119
164
  return [
120
- `ALRT History needs a free Gloom sign-in: it lists the alerts Gloom delivered to your account over the last 90 days. ${verifyEmail ? "Until the email is verified" : "Signed out"} it shows none of them.`,
121
- `To read it, open the app (gloomberb), ${account}; gloomberb fn ALRT --tab history then reads with that session.`,
165
+ `Only the alerts this app fired are listed: the ones Gloom Cloud delivered to your phone or email over the last 90 days need a free Gloom sign-in${verifyEmail ? " with a verified email" : ""}.`,
166
+ `To add them, open the app (gloom), ${account}; gloom fn ALRT --tab history then reads with that session.`,
122
167
  ].join("\n");
123
168
  }
124
169
 
170
+ /** The app's own fired alerts, newest first, with Gloom Cloud's deliveries merged in when the session can read them. */
125
171
  async function historyResult(ctx: HeadlessPaneContext): Promise<HeadlessRowsResult> {
172
+ const fired = readFiredAlerts(ctx.readDeviceState?.(ALERTS_PLUGIN_ID, FIRED_LOG_KEY));
126
173
  const items: AlertHistoryItem[] = [];
127
174
  let first: AlertHistory | null = null;
128
175
  let more = false;
176
+ let refused: string | null = null;
177
+ let failed: string | null = null;
129
178
  try {
130
179
  for (let offset: number | null = 0, page = 0; offset != null; page += 1) {
131
180
  if (page === HISTORY_PAGES) {
@@ -139,28 +188,38 @@ async function historyResult(ctx: HeadlessPaneContext): Promise<HeadlessRowsResu
139
188
  offset = history.hasMore ? history.nextOffset : null;
140
189
  }
141
190
  } catch (error) {
142
- throw await explainRefusal(error, alertHistoryLockNote, { symbol: null, token: "ALRT" });
191
+ // Signed out, the app's own log is the history; any other failure is said beside it.
192
+ const lock = refusedLock(error);
193
+ if (lock?.gate === "sign-in") refused = alertHistoryLockNote({ ...lock, symbol: null, token: "ALRT" });
194
+ else failed = error instanceof Error ? error.message : String(error);
143
195
  }
144
196
  const unavailable = first?.status === "unavailable";
197
+ const rows = mergeAlertHistory(fired, items).map(historyRow);
198
+ const errors = [...unavailable ? [first?.warning ?? "Delivered alerts are unavailable."] : [], ...failed ? [`Delivered alerts: ${failed}`] : []];
199
+ const notes = [
200
+ ...refused ? [refused] : [],
201
+ ...more ? [`Showing the latest ${items.length} delivered alerts; the pane loads older ones as you scroll.`] : [],
202
+ ];
145
203
  return {
146
204
  columns: HISTORY_COLUMNS,
147
- rows: items.map(historyRow),
148
- empty: "No alerts delivered in the last 90 days.",
149
- freshness: { source: "Gloom Cloud", status: "not-a-feed", basis: "delivered alerts", ...(first ? { asOf: first.asOf } : {}) },
150
- ...(unavailable ? { errors: [first?.warning ?? "Alert history is unavailable."], complete: false } : {}),
151
- ...(more ? { notes: [`Showing the latest ${items.length} delivered alerts; the pane loads older ones as you scroll.`] } : {}),
205
+ textColumns: HISTORY_TEXT_COLUMNS,
206
+ rows,
207
+ empty: refused ? "This app has fired no alerts yet." : "No alerts fired by this app or delivered in the last 90 days.",
208
+ freshness: { source: first ? "This app and Gloom Cloud" : "This app", status: "not-a-feed", basis: "fired and delivered alerts", ...(first ? { asOf: first.asOf } : {}) },
209
+ ...(errors.length ? { errors, complete: false } : {}),
210
+ ...(notes.length ? { notes } : {}),
152
211
  metadata: { deviceEnabled: first?.deviceEnabled ?? null },
153
212
  };
154
213
  }
155
214
 
156
215
  export const alertsHeadless: HeadlessPaneDefinition<"rows"> = {
157
216
  shape: "rows",
158
- description: "Your alerts: price alerts with current price and distance to target, event alerts (earnings, CPI and FOMC dates, filings, news, market moves) or the alerts delivered to your account.",
217
+ description: "Your alerts: price alerts with current price and distance to target, event alerts (earnings, CPI, FOMC and other economic calendar releases, filings, news, IV levels, market moves) or the alerts that went off, from this app and, signed in, Gloom Cloud.",
159
218
  freshness: { source: "Your alerts", status: "not-a-feed", basis: "your alert rules" },
160
219
  argument: { kind: "none" },
161
220
  options: [{
162
221
  key: "tab",
163
- description: "Alerts tab: prices, events or history (delivered alerts, signed in).",
222
+ description: "Alerts tab: prices, events or history (alerts that went off; Gloom Cloud's deliveries when signed in).",
164
223
  type: "enum",
165
224
  values: ALERT_TABS.map(({ value }) => ({ value })),
166
225
  defaultValue: "prices",
@@ -169,7 +228,7 @@ export const alertsHeadless: HeadlessPaneDefinition<"rows"> = {
169
228
  }],
170
229
  discovery: {
171
230
  screenshotReadiness: "live-dom",
172
- dataRequirements: ["Your saved alerts; the History tab needs a Gloom sign-in"],
231
+ dataRequirements: ["Your saved alerts and this device's log of fired alerts; History adds Gloom Cloud's deliveries when signed in"],
173
232
  limitations: ["Current price and quote time are what the app saved at its last check, blank until it has checked the alert."],
174
233
  },
175
234
  describe: (args) => `Alerts | ${String(args.options.tab ?? "prices")}`,
@@ -177,6 +236,8 @@ export const alertsHeadless: HeadlessPaneDefinition<"rows"> = {
177
236
  const tab = (args.options.tab ?? "prices") as AlertsTab;
178
237
  if (tab === "history") return historyResult(ctx);
179
238
  const { alerts, alertsError, events } = readAlertStores(ctx.config);
180
- return tab === "events" ? eventsResult(events.rules, events.error) : pricesResult(alerts, alertsError, events.rules.length);
239
+ return tab === "events"
240
+ ? eventsResult(events.rules, events.error, readIvLevelChecks(ctx.readDeviceState?.(ALERTS_PLUGIN_ID, IV_LEVEL_CHECKS_KEY)))
241
+ : pricesResult(alerts, alertsError, events.rules.length);
181
242
  },
182
243
  };
@@ -12,20 +12,55 @@ import { handleRefreshKey } from "../../../components/data-table/table-pane";
12
12
  import { colors } from "../../../theme/colors";
13
13
  import type { PaneProps } from "../../../types/plugin";
14
14
  import type { ScrollBoxRenderable } from "../../../ui";
15
- import { SignInWall } from "../cloud/auth-actions";
16
15
  import { usePlanAccess } from "../../../api-client/plan-access";
16
+ import { usePluginState } from "../../runtime";
17
17
  import { useResearchCloudSession } from "../shared/research-cloud-session";
18
+ import { FIRED_LOG_KEY, readFiredAlerts } from "./fired-log";
18
19
  import { alertKindLabel, fetchAlertHistory, type AlertHistoryItem } from "./history";
20
+ import { mergeAlertHistory, type AlertHistoryRow, type AlertHistoryVia } from "./history-rows";
19
21
  import { relativeTime } from "./format";
20
- import { alertTarget, alertViewHints, deliveredAlertSubject, useOpenAlertTarget } from "./targets";
22
+ import { alertTarget, alertViewHints, deliveredAlertSubject, useOpenAlertTarget, type AlertSubject } from "./targets";
21
23
 
22
24
  const stamp = (value: string) => value.slice(0, 16).replace("T", " ");
23
25
  const itemId = (item: AlertHistoryItem) => item.id;
26
+ /** Where a line comes from, in the Via column's few cells. */
27
+ const VIA_TEXT: Record<AlertHistoryVia, string> = { app: "App", cloud: "Cloud", both: "App, Cloud" };
24
28
 
25
- /** Alerts the push service accepted for this account over the last 90 days. */
29
+ /** One line of History: an alert this app fired, one Gloom Cloud delivered, or both for the one alert. */
30
+ interface HistoryRow {
31
+ id: string;
32
+ time: string;
33
+ kind: string;
34
+ alert: string;
35
+ /** The figure in its unit, or what the alert said. */
36
+ value: string;
37
+ quoteAt: string | null;
38
+ source: string;
39
+ via: AlertHistoryVia;
40
+ subject: AlertSubject;
41
+ }
42
+
43
+ function historyRow(row: AlertHistoryRow): HistoryRow {
44
+ const figure = row.value == null ? null
45
+ : `${Number(row.value.toFixed(4))}${row.unit === "%" ? "%" : row.unit ? ` ${row.unit}` : ""}`;
46
+ return {
47
+ id: row.id, time: row.time, kind: row.kind, alert: row.alert, value: figure ?? row.detail,
48
+ quoteAt: row.quoteAt, source: row.source ?? "", via: row.via,
49
+ subject: row.fired
50
+ ? { kind: row.fired.kind, symbol: row.fired.symbol, exchange: row.fired.exchange }
51
+ : deliveredAlertSubject(row.delivered!),
52
+ };
53
+ }
54
+
55
+ /**
56
+ * The alerts that went off, newest first: the ones this app fired, kept on the device, and, signed in,
57
+ * the ones Gloom Cloud delivered to the account's phone or email over the last 90 days.
58
+ */
26
59
  export function AlertHistoryPane({ focused, width, height }: PaneProps) {
27
60
  const access = usePlanAccess();
28
61
  const session = useResearchCloudSession();
62
+ const [firedLog] = usePluginState<unknown>(FIRED_LOG_KEY, []);
63
+ const fired = useMemo(() => readFiredAlerts(firedLog), [firedLog]);
29
64
  const [selected, setSelected] = useState(0);
30
65
  // A new session starts the history over. A failed later page leaves what is
31
66
  // loaded, and the next scroll to the end asks again.
@@ -35,84 +70,92 @@ export function AlertHistoryPane({ focused, width, height }: PaneProps) {
35
70
  }, [session.requestKey]);
36
71
  const history = usePagedRows(access.signedIn ? loadPage : null, { getId: itemId });
37
72
  const data = history.pages[0] ?? null;
38
- const items = history.rows;
73
+ const cloudError = access.signedIn
74
+ ? data?.status === "unavailable" ? data.warning ?? "Delivered alerts are unavailable." : !data ? history.error?.message ?? null : null
75
+ : null;
76
+ // One line per alert: a delivery of one this app fired too joins its line.
77
+ const items = useMemo(
78
+ () => mergeAlertHistory(fired, data?.status === "unavailable" ? [] : history.rows).map(historyRow),
79
+ [fired, data, history.rows],
80
+ );
39
81
  const loadingMore = history.loadingMore;
40
82
  const scrollRef = useRef<ScrollBoxRenderable | null>(null);
41
83
  const loadMoreOnScroll = useTableLoadMore(scrollRef, history.hasMore && !loadingMore, history.loadMore);
42
- const selectedItem = items[Math.min(selected, Math.max(0, items.length - 1))];
43
- const selectedTarget = useMemo(() => selectedItem ? alertTarget(deliveredAlertSubject(selectedItem)) : null, [selectedItem]);
84
+ const selectedIndex = Math.min(selected, Math.max(0, items.length - 1));
85
+ const selectedItem = items[selectedIndex];
86
+ const selectedTarget = useMemo(() => selectedItem ? alertTarget(selectedItem.subject) : null, [selectedItem]);
44
87
  const openTarget = useOpenAlertTarget();
45
88
 
46
89
  const columns: DataTableColumn[] = [
47
- { id: "time", label: "Sent (UTC)", width: 16, align: "left" },
90
+ { id: "time", label: "Time (UTC)", width: 16, align: "left" },
48
91
  { id: "kind", label: "Event", width: 15, align: "left" },
49
- { id: "title", label: "Alert", width: Math.max(16, Math.min(28, width - 60)), align: "left" },
50
- ...(width >= 70 ? [{ id: "body", label: "Detail", width: 20, flexGrow: 1, align: "left" as const }] : []),
92
+ { id: "alert", label: "Alert", width: 20, flexGrow: 1, align: "left" },
93
+ ...(width >= 70 ? [{ id: "value", label: "Value", width: 16, align: "left" as const }] : []),
94
+ ...(width >= 115
95
+ ? [
96
+ { id: "quote", label: "Quote (UTC)", width: 16, align: "left" as const },
97
+ { id: "source", label: "Source", width: 14, align: "left" as const },
98
+ { id: "via", label: "Via", width: 10, align: "left" as const },
99
+ ]
100
+ : []),
51
101
  ];
52
102
  usePaneFooter(
53
103
  "alert-history",
54
104
  () => ({
55
- info: data
56
- ? [
57
- ...(loadingMore ? [{ id: "more", parts: [{ text: "loading more", tone: "muted" as const }] }] : []),
58
- {
105
+ info: [
106
+ ...(loadingMore ? [{ id: "more", parts: [{ text: "loading more", tone: "muted" as const }] }] : []),
107
+ ...(cloudError && items.length > 0 ? [{ id: "cloud-error", parts: [{ text: cloudError, tone: "warning" as const }] }] : []),
108
+ ...(data && data.status !== "unavailable"
109
+ ? [{
59
110
  id: "device",
60
- parts: [
61
- {
62
- text: `${data.deviceEnabled ? "phone connected" : "no phone connected"} · checked ${relativeTime(Date.parse(data.asOf))}`,
63
- tone: data.deviceEnabled ? ("muted" as const) : ("warning" as const),
64
- },
65
- ],
66
- },
67
- ]
68
- : [],
111
+ parts: [{
112
+ text: `${data.deviceEnabled ? "phone connected" : "no phone connected"} · checked ${relativeTime(Date.parse(data.asOf))}`,
113
+ tone: data.deviceEnabled ? ("muted" as const) : ("warning" as const),
114
+ }],
115
+ }]
116
+ : []),
117
+ ...(!access.signedIn ? [{ id: "account", parts: [{ text: "signed out · this app's alerts only", tone: "muted" as const }] }] : []),
118
+ ],
69
119
  hints: alertViewHints(selectedTarget, openTarget),
70
120
  }),
71
- [data, loadingMore, selectedTarget, openTarget],
121
+ [data, loadingMore, cloudError, items.length, access.signedIn, selectedTarget, openTarget],
72
122
  );
73
- if (!access.signedIn)
74
- return <SignInWall placement="alerts-history-signin" action="see delivered alerts" needsVerification={session.needsVerification} />;
75
123
  return (
76
124
  <PaneStatusBody
77
- loading={history.loading && !data}
78
- error={!data ? history.error?.message ?? null : null}
125
+ loading={history.loading && !data && fired.length === 0}
126
+ error={cloudError && items.length === 0 ? cloudError : null}
79
127
  subject="alert history"
80
128
  >
81
- {data?.status === "unavailable" ? (
82
- <PaneStatusBody error={data.warning ?? "Alert history is unavailable."} subject="alert history" />
83
- ) : (
84
- <DataTableView<AlertHistoryItem, DataTableColumn>
85
- focused={focused}
86
- rootWidth={width}
87
- rootHeight={height}
88
- columns={columns}
89
- items={items}
90
- scrollRef={scrollRef}
91
- onBodyScrollActivity={loadMoreOnScroll}
92
- selection={{
93
- kind: "index",
94
- selectedIndex: Math.min(selected, Math.max(0, items.length - 1)),
95
- onChange: setSelected,
96
- }}
97
- getItemKey={(item) => item.id}
98
- onRootKeyDown={(event) => handleRefreshKey(event, history.reload)}
99
- sortColumnId={null}
100
- sortDirection="desc"
101
- renderCell={(item, column, _index, row) => ({
102
- text:
103
- column.id === "time"
104
- ? stamp(item.deliveredAt)
105
- : column.id === "kind"
106
- ? alertKindLabel(item.kind)
107
- : column.id === "title"
108
- ? item.title
109
- : item.body,
110
- color: row.selected ? colors.selectedText : column.id === "time" ? colors.textMuted : colors.text,
111
- })}
112
- emptyStateTitle="No alerts delivered in the last 90 days"
113
- emptyStateHint={data?.deviceEnabled ? undefined : "Alerts push to the Gloomberb phone app once it is signed in."}
114
- />
115
- )}
129
+ <DataTableView<HistoryRow, DataTableColumn>
130
+ focused={focused}
131
+ rootWidth={width}
132
+ rootHeight={height}
133
+ columns={columns}
134
+ items={items}
135
+ scrollRef={scrollRef}
136
+ onBodyScrollActivity={loadMoreOnScroll}
137
+ selection={{ kind: "index", selectedIndex, onChange: setSelected }}
138
+ getItemKey={(item) => item.id}
139
+ onRootKeyDown={(event) => handleRefreshKey(event, history.reload)}
140
+ sortColumnId={null}
141
+ sortDirection="desc"
142
+ renderCell={(item, column, _index, row) => ({
143
+ text:
144
+ column.id === "time" ? stamp(item.time)
145
+ : column.id === "kind" ? alertKindLabel(item.kind)
146
+ : column.id === "alert" ? item.alert
147
+ : column.id === "value" ? item.value
148
+ : column.id === "quote" ? (item.quoteAt ? stamp(item.quoteAt) : "")
149
+ : column.id === "via" ? VIA_TEXT[item.via]
150
+ : item.source,
151
+ color: row.selected ? colors.selectedText
152
+ : column.id === "time" || column.id === "quote" || column.id === "source" || column.id === "via" ? colors.textMuted : colors.text,
153
+ })}
154
+ emptyStateTitle={access.signedIn ? "No alerts in the last 90 days" : "No alerts fired yet"}
155
+ emptyStateHint={access.signedIn
156
+ ? data?.deviceEnabled ? undefined : "Alerts push to the Gloom phone app once it is signed in."
157
+ : "Sign in to list the alerts Gloom Cloud delivers too."}
158
+ />
116
159
  </PaneStatusBody>
117
160
  );
118
161
  }
@@ -0,0 +1,89 @@
1
+ import type { FiredAlert } from "./fired-log";
2
+ import type { AlertHistoryItem } from "./history";
3
+
4
+ /** Where a line of History comes from: this app's log, Gloom Cloud's deliveries, or both for the one alert. */
5
+ export type AlertHistoryVia = "app" | "cloud" | "both";
6
+
7
+ export const ALERT_HISTORY_VIA: Record<AlertHistoryVia, string> = {
8
+ app: "This app",
9
+ cloud: "Gloom Cloud",
10
+ both: "This app and Gloom Cloud",
11
+ };
12
+
13
+ /** One alert that went off, as History lists it. */
14
+ export interface AlertHistoryRow {
15
+ id: string;
16
+ /** When it went off: the app's own time when it fired it, otherwise Gloom Cloud's delivery. */
17
+ time: string;
18
+ via: AlertHistoryVia;
19
+ kind: string;
20
+ /** The rule as the app read it, or the notification's title. */
21
+ alert: string;
22
+ value: number | null;
23
+ unit: string | null;
24
+ quoteAt: string | null;
25
+ source: string | null;
26
+ /** What the notification said beside the figure. */
27
+ detail: string;
28
+ fired?: FiredAlert;
29
+ delivered?: AlertHistoryItem;
30
+ }
31
+
32
+ /**
33
+ * How far apart the app and Gloom Cloud send the same alert: a price alert is
34
+ * checked minutes apart by each; an earnings alert goes off once on its day.
35
+ */
36
+ const PRICE_MATCH_MS = 60 * 60_000;
37
+ const EVENT_MATCH_MS = 24 * 3_600_000;
38
+
39
+ const upper = (value: unknown) => (typeof value === "string" && value ? value.toUpperCase() : null);
40
+
41
+ /**
42
+ * Whether a Cloud delivery is the same alert the app fired: the same price
43
+ * alert (Gloom Cloud names its id), or the same kind of alert on the same
44
+ * symbol, within the time the two take to send it.
45
+ */
46
+ function sameAlert(entry: FiredAlert, item: AlertHistoryItem): boolean {
47
+ if (item.kind !== entry.kind) return false;
48
+ const apart = Math.abs(Date.parse(item.deliveredAt) - Date.parse(entry.firedAt));
49
+ if (!Number.isFinite(apart)) return false;
50
+ if (entry.kind === "price") return item.data?.alertId === entry.ruleId && apart <= PRICE_MATCH_MS;
51
+ const symbol = upper(item.data?.symbol);
52
+ return !!symbol && symbol === upper(entry.symbol) && apart <= EVENT_MATCH_MS;
53
+ }
54
+
55
+ function firedRow(entry: FiredAlert, delivered: AlertHistoryItem | undefined): AlertHistoryRow {
56
+ return {
57
+ id: `app:${entry.id}`, time: entry.firedAt, via: delivered ? "both" : "app", kind: entry.kind, alert: entry.rule,
58
+ value: entry.value, unit: entry.unit ?? null, quoteAt: entry.quoteAt, source: entry.source,
59
+ detail: entry.detail ?? delivered?.body ?? "", fired: entry, ...delivered ? { delivered } : {},
60
+ };
61
+ }
62
+
63
+ function deliveredRow(item: AlertHistoryItem): AlertHistoryRow {
64
+ return {
65
+ id: `cloud:${item.id}`, time: item.deliveredAt, via: "cloud", kind: item.kind, alert: item.title,
66
+ value: null, unit: null, quoteAt: null, source: null, detail: item.body, delivered: item,
67
+ };
68
+ }
69
+
70
+ /**
71
+ * The alerts this app fired and the ones Gloom Cloud delivered, newest first,
72
+ * one line per alert: a delivery of an alert the app fired too is that line,
73
+ * with the app's figure and quote and `both` as where it came from.
74
+ */
75
+ export function mergeAlertHistory(fired: readonly FiredAlert[], delivered: readonly AlertHistoryItem[]): AlertHistoryRow[] {
76
+ const matched = new Set<AlertHistoryItem>();
77
+ const rows = [...fired]
78
+ .sort((a, b) => Date.parse(b.firedAt) - Date.parse(a.firedAt))
79
+ .map((entry) => {
80
+ // The nearest delivery in time, each matched once.
81
+ const candidates = delivered.filter((item) => !matched.has(item) && sameAlert(entry, item));
82
+ const nearest = candidates.sort((a, b) => Math.abs(Date.parse(a.deliveredAt) - Date.parse(entry.firedAt))
83
+ - Math.abs(Date.parse(b.deliveredAt) - Date.parse(entry.firedAt)))[0];
84
+ if (nearest) matched.add(nearest);
85
+ return firedRow(entry, nearest);
86
+ });
87
+ rows.push(...delivered.filter((item) => !matched.has(item)).map(deliveredRow));
88
+ return rows.sort((a, b) => Date.parse(b.time) - Date.parse(a.time));
89
+ }