gloomberb 0.11.2 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (531) hide show
  1. package/README.md +7 -4
  2. package/README.zh-CN.md +4 -2
  3. package/package.json +28 -1
  4. package/src/api-client/auth.ts +10 -0
  5. package/src/api-client/data.ts +108 -1
  6. package/src/api-client/index.test.ts +127 -0
  7. package/src/api-client/index.ts +134 -1
  8. package/src/api-client/normalizers.ts +39 -0
  9. package/src/api-client/paths.ts +85 -1
  10. package/src/api-client/types.ts +220 -0
  11. package/src/app/pane-runtime/index.tsx +15 -12
  12. package/src/app/pane-runtime/layout-placement.test.ts +27 -0
  13. package/src/app/pane-runtime/layout-placement.ts +13 -0
  14. package/src/app/pane-runtime/plugin-bindings.ts +62 -0
  15. package/src/app.tsx +60 -18
  16. package/src/architecture/browser-entry-graph.test.ts +96 -0
  17. package/src/brokers/profile-form.test.ts +25 -27
  18. package/src/brokers/test-broker.ts +68 -0
  19. package/src/capabilities/chart-series.ts +3 -2
  20. package/src/cli/commands/market.ts +2 -2
  21. package/src/cli/commands/plugins.ts +39 -11
  22. package/src/cli/desktop-pane-shot.ts +285 -16
  23. package/src/cli/index.ts +1 -1
  24. package/src/cli/pane-functions/capabilities.ts +61 -31
  25. package/src/cli/pane-functions/catalog.ts +16 -4
  26. package/src/cli/pane-functions/discovery.ts +1 -0
  27. package/src/cli/pane-functions/headless.test.ts +247 -0
  28. package/src/cli/pane-functions/headless.ts +423 -0
  29. package/src/cli/pane-functions/index.test.ts +9 -0
  30. package/src/cli/pane-functions/index.ts +6 -2
  31. package/src/cli/pane-functions/options.ts +27 -2
  32. package/src/cli/pane-functions/report.ts +4 -0
  33. package/src/cli/pane-functions/resolver.ts +26 -8
  34. package/src/cli/pane-functions/screenshot.test.ts +76 -0
  35. package/src/cli/pane-functions/screenshot.ts +236 -20
  36. package/src/cli/registry.ts +0 -22
  37. package/src/cli/restore-plugins.ts +34 -0
  38. package/src/cli/result.ts +7 -10
  39. package/src/components/chart/{static/chart → composite}/axis-overlays.test.tsx +3 -3
  40. package/src/components/chart/{static/chart → composite}/axis-overlays.tsx +6 -11
  41. package/src/components/chart/{static/chart → composite}/bitmap.ts +17 -3
  42. package/src/components/chart/composite/composite-chart.test.tsx +68 -20
  43. package/src/components/chart/composite/composite-chart.tsx +301 -204
  44. package/src/components/chart/composite/format.ts +8 -2
  45. package/src/components/chart/composite/interactions.test.ts +68 -102
  46. package/src/components/chart/composite/interactions.ts +214 -264
  47. package/src/components/chart/composite/price-axis-labels.test.ts +21 -0
  48. package/src/components/chart/{price-axis-labels.tsx → composite/price-axis-labels.tsx} +9 -4
  49. package/src/components/chart/composite/scene.ts +57 -3
  50. package/src/components/chart/composite/text-renderer.ts +3 -2
  51. package/src/components/chart/composite/time-scale.ts +138 -57
  52. package/src/components/chart/composite/types.ts +25 -1
  53. package/src/components/chart/core/data.ts +9 -13
  54. package/src/components/chart/core/date-window.ts +7 -1
  55. package/src/components/chart/core/pointer.ts +3 -0
  56. package/src/components/chart/core/types.ts +0 -45
  57. package/src/components/chart/native/chart-rasterizer.ts +0 -1
  58. package/src/components/chart/native/kitty/index.test.ts +0 -188
  59. package/src/components/chart/native/raster/crosshair.ts +6 -5
  60. package/src/components/chart/native/raster/primitives.ts +0 -23
  61. package/src/components/chart/native/renderer-selection.ts +81 -31
  62. package/src/components/chart/static/{chart/surface.test.tsx → chart-surface.test.tsx} +28 -80
  63. package/src/components/chart/static/chart-surface.tsx +150 -0
  64. package/src/components/chart/static/index.ts +8 -0
  65. package/src/components/chart/static/multi-line-chart-surface.tsx +51 -166
  66. package/src/components/chart/static/scatter-chart-surface.test.ts +30 -0
  67. package/src/components/chart/static/scatter-chart-surface.tsx +135 -34
  68. package/src/components/chart/static/series.ts +49 -0
  69. package/src/components/command-bar/action-runtime.ts +1 -3
  70. package/src/components/command-bar/assist/model.test.ts +17 -2
  71. package/src/components/command-bar/assist/model.ts +40 -9
  72. package/src/components/command-bar/commands/direct/index.ts +1 -1
  73. package/src/components/command-bar/commands/direct/runtime.ts +1 -1
  74. package/src/components/command-bar/commands/registry.ts +0 -11
  75. package/src/components/command-bar/helpers.test.ts +2 -2
  76. package/src/components/command-bar/helpers.ts +2 -6
  77. package/src/components/command-bar/keyboard-shortcuts.ts +0 -11
  78. package/src/components/command-bar/list/badge.test.ts +54 -0
  79. package/src/components/command-bar/list/badge.ts +62 -0
  80. package/src/components/command-bar/list/model.test.ts +103 -0
  81. package/src/components/command-bar/list/model.ts +61 -4
  82. package/src/components/command-bar/list/view.test.tsx +113 -0
  83. package/src/components/command-bar/list/view.tsx +147 -131
  84. package/src/components/command-bar/pane-templates/workflow.ts +1 -1
  85. package/src/components/command-bar/panel/body.tsx +51 -65
  86. package/src/components/command-bar/panel/index.tsx +48 -13
  87. package/src/components/command-bar/panel/layout.test.ts +139 -0
  88. package/src/components/command-bar/panel/layout.ts +65 -28
  89. package/src/components/command-bar/panel/native-surface.ts +24 -0
  90. package/src/components/command-bar/panel/prompt-binding.ts +54 -0
  91. package/src/components/command-bar/panel/runtime.ts +6 -3
  92. package/src/components/command-bar/panel/state.ts +41 -7
  93. package/src/components/command-bar/panel/types.ts +7 -1
  94. package/src/components/command-bar/routes/root/provider-search.ts +34 -15
  95. package/src/components/command-bar/routes/root/results.test.ts +161 -0
  96. package/src/components/command-bar/routes/root/results.ts +30 -28
  97. package/src/components/command-bar/routes/root/runtime.ts +37 -20
  98. package/src/components/command-bar/routes/root/search-providers.test.tsx +224 -0
  99. package/src/components/command-bar/routes/root/search-providers.ts +205 -0
  100. package/src/components/command-bar/routes/root/selection.ts +1 -12
  101. package/src/components/command-bar/routes/root/shortcuts.test.ts +8 -8
  102. package/src/components/command-bar/routes/ticker-search/actions.ts +10 -9
  103. package/src/components/command-bar/routes/ticker-search/results.test.ts +54 -1
  104. package/src/components/command-bar/routes/ticker-search/results.ts +60 -19
  105. package/src/components/command-bar/routes/ticker-search/route.ts +1 -0
  106. package/src/components/command-bar/routing/actions.ts +1 -81
  107. package/src/components/command-bar/routing/launch-request.ts +1 -1
  108. package/src/components/command-bar/routing/list-state.ts +6 -21
  109. package/src/components/command-bar/selection-runtime.ts +1 -1
  110. package/src/components/command-bar/surface/assist.test.tsx +14 -10
  111. package/src/components/command-bar/surface/environment.ts +8 -1
  112. package/src/components/command-bar/surface/index.test.tsx +84 -68
  113. package/src/components/command-bar/surface/index.tsx +33 -36
  114. package/src/components/command-bar/surface/test-harness.tsx +15 -3
  115. package/src/components/command-bar/theme-picker.tsx +43 -15
  116. package/src/components/command-bar/view-model.test.ts +53 -8
  117. package/src/components/command-bar/view-model.ts +43 -14
  118. package/src/components/command-bar/workflow/tickers.ts +1 -0
  119. package/src/components/command-bar/workflow/types.ts +1 -1
  120. package/src/components/data-table/export.test.ts +21 -0
  121. package/src/components/data-table/export.ts +21 -0
  122. package/src/components/data-table/view.test.tsx +45 -6
  123. package/src/components/data-table/view.tsx +55 -9
  124. package/src/components/index.ts +10 -2
  125. package/src/components/input-search-bar.test.tsx +36 -2
  126. package/src/components/input-search-bar.tsx +18 -1
  127. package/src/components/layout/header.test.tsx +57 -10
  128. package/src/components/layout/header.tsx +292 -149
  129. package/src/components/layout/market-summary.test.ts +81 -0
  130. package/src/components/layout/market-summary.ts +109 -0
  131. package/src/components/layout/shell/chrome.ts +96 -1
  132. package/src/components/layout/shell/index.tsx +11 -3
  133. package/src/components/layout/shell/menu.ts +9 -0
  134. package/src/components/layout/shell/pane/actions.ts +29 -0
  135. package/src/components/layout/shell/pane/management-shortcuts.ts +5 -0
  136. package/src/components/layout/shell/shortcuts.ts +3 -0
  137. package/src/components/layout/status-bar.test.tsx +9 -8
  138. package/src/components/layout/status-bar.tsx +85 -54
  139. package/src/components/onboarding/onboarding-frame.tsx +2 -26
  140. package/src/components/price-sparkline/index.ts +61 -34
  141. package/src/components/price-sparkline/view.tsx +1 -1
  142. package/src/components/sign-in-gate.test.tsx +128 -0
  143. package/src/components/sign-in-gate.tsx +149 -0
  144. package/src/components/speedometer-gauge/desktop.tsx +2 -12
  145. package/src/components/ticker/badge/list.tsx +17 -3
  146. package/src/components/ticker/list-table-view.tsx +6 -3
  147. package/src/components/ui/data-table/index.tsx +22 -4
  148. package/src/components/ui/data-table/opentui/index.tsx +165 -120
  149. package/src/components/ui/frame.tsx +28 -0
  150. package/src/components/ui/index.ts +3 -0
  151. package/src/components/ui/native-select.tsx +20 -10
  152. package/src/components/ui/select-button.tsx +138 -0
  153. package/src/components/ui/status.tsx +2 -2
  154. package/src/components/ui/table-layout.ts +1 -1
  155. package/src/components/use-double-click-activation.ts +7 -3
  156. package/src/core/app-services.ts +3 -3
  157. package/src/data/config/chart-settings.ts +4 -4
  158. package/src/data/config/layout.ts +12 -6
  159. package/src/data/config/store/index.test.ts +97 -0
  160. package/src/data/config/store/migrations.ts +41 -0
  161. package/src/data/config/store/normalize.ts +5 -3
  162. package/src/i18n/es.ts +6 -2
  163. package/src/i18n/ja.ts +6 -2
  164. package/src/i18n/ko.ts +6 -2
  165. package/src/i18n/zh-cn.ts +6 -2
  166. package/src/i18n/zh-tw.ts +6 -2
  167. package/src/layout-marketplace/gallery-terminal.tsx +126 -96
  168. package/src/layout-marketplace/gallery.test.tsx +65 -1
  169. package/src/layout-marketplace/pane-imagery.ts +1 -0
  170. package/src/layout-marketplace/payload.test.ts +17 -0
  171. package/src/layout-marketplace/payload.ts +40 -5
  172. package/src/market-data/coordinator/index.ts +3 -2
  173. package/src/market-data/coordinator/quotes.ts +173 -66
  174. package/src/market-data/coordinator/subscriptions.test.ts +215 -37
  175. package/src/pane-settings.ts +1 -1
  176. package/src/plugins/builtin/analytics/pane-model.ts +1 -1
  177. package/src/plugins/builtin/analytics/view.tsx +1 -1
  178. package/src/plugins/builtin/broker-manager/index.test.tsx +3 -2
  179. package/src/plugins/builtin/broker-manager/model.test.ts +2 -2
  180. package/src/plugins/builtin/chart-composer/catalog-inventory.ts +16 -2
  181. package/src/plugins/builtin/chart-composer/cli-options.ts +12 -9
  182. package/src/plugins/builtin/chart-composer/pane.tsx +22 -8
  183. package/src/plugins/builtin/chart-composer/settings.ts +2 -13
  184. package/src/plugins/builtin/chat/content/composer.tsx +8 -4
  185. package/src/plugins/builtin/cloud/auth-dialog.tsx +14 -228
  186. package/src/plugins/builtin/cloud/auth-form.tsx +277 -0
  187. package/src/plugins/builtin/cloud/plugin.tsx +1 -0
  188. package/src/plugins/builtin/composite-plugins.ts +16 -1
  189. package/src/plugins/builtin/correlation/relationship/model.ts +1 -1
  190. package/src/plugins/builtin/correlation/relationship/pane.tsx +2 -6
  191. package/src/plugins/builtin/correlation/relationship/view-model.ts +2 -2
  192. package/src/plugins/builtin/credit-conditions/index.test.tsx +12 -6
  193. package/src/plugins/builtin/credit-conditions/index.tsx +2 -21
  194. package/src/plugins/builtin/dividend-yield/index.tsx +1 -0
  195. package/src/plugins/builtin/dividend-yield/pane.tsx +1 -1
  196. package/src/plugins/builtin/earnings/index.tsx +1 -0
  197. package/src/plugins/builtin/earnings-calls/data.ts +223 -0
  198. package/src/plugins/builtin/earnings-calls/format.ts +49 -0
  199. package/src/plugins/builtin/earnings-calls/index.tsx +69 -0
  200. package/src/plugins/builtin/earnings-calls/pane.tsx +756 -0
  201. package/src/plugins/builtin/earnings-calls/prose.test.ts +36 -0
  202. package/src/plugins/builtin/earnings-calls/prose.ts +59 -0
  203. package/src/plugins/builtin/earnings-calls/transcript-view.tsx +334 -0
  204. package/src/plugins/builtin/econ/detail-view.tsx +1 -2
  205. package/src/plugins/builtin/econ/fred-series-map.ts +16 -1
  206. package/src/plugins/builtin/econ/index.tsx +3 -1
  207. package/src/plugins/builtin/econ-statistics/cache.ts +4 -0
  208. package/src/plugins/builtin/econ-statistics/client.ts +92 -0
  209. package/src/plugins/builtin/econ-statistics/defs.ts +66 -0
  210. package/src/plugins/builtin/econ-statistics/detail.tsx +154 -0
  211. package/src/plugins/builtin/econ-statistics/headless.test.ts +54 -0
  212. package/src/plugins/builtin/econ-statistics/headless.ts +171 -0
  213. package/src/plugins/builtin/econ-statistics/index.tsx +54 -0
  214. package/src/plugins/builtin/econ-statistics/pane.tsx +356 -0
  215. package/src/plugins/builtin/econ-statistics/stats.ts +522 -0
  216. package/src/plugins/builtin/econ-statistics/transform.test.ts +86 -0
  217. package/src/plugins/builtin/econ-statistics/transform.ts +85 -0
  218. package/src/plugins/builtin/econ-statistics/trend.ts +57 -0
  219. package/src/plugins/builtin/econ-statistics/view.ts +90 -0
  220. package/src/plugins/builtin/fear-greed/charts.tsx +7 -18
  221. package/src/plugins/builtin/fear-greed/data.ts +6 -1
  222. package/src/plugins/builtin/futures/index.tsx +1 -0
  223. package/src/plugins/builtin/fx-matrix/index.tsx +1 -0
  224. package/src/plugins/builtin/help/index.tsx +4 -0
  225. package/src/plugins/builtin/holders/index.tsx +1 -0
  226. package/src/plugins/builtin/insider/index.tsx +1 -0
  227. package/src/plugins/builtin/ipo-calendar/index.tsx +1 -0
  228. package/src/plugins/builtin/kelly-sizer/pane.tsx +1 -1
  229. package/src/plugins/builtin/kelly-sizer/sections.tsx +2 -3
  230. package/src/plugins/builtin/market-halts/index.tsx +1 -0
  231. package/src/plugins/builtin/market-movers/index.tsx +1 -0
  232. package/src/plugins/builtin/market-valuation/align.ts +122 -0
  233. package/src/plugins/builtin/market-valuation/cache.ts +32 -0
  234. package/src/plugins/builtin/market-valuation/chart-projection.ts +217 -0
  235. package/src/plugins/builtin/market-valuation/chart-series.ts +89 -0
  236. package/src/plugins/builtin/market-valuation/client.test.ts +141 -0
  237. package/src/plugins/builtin/market-valuation/client.ts +116 -0
  238. package/src/plugins/builtin/market-valuation/defs.ts +251 -0
  239. package/src/plugins/builtin/market-valuation/detail.tsx +159 -0
  240. package/src/plugins/builtin/market-valuation/headless.test.ts +58 -0
  241. package/src/plugins/builtin/market-valuation/headless.ts +170 -0
  242. package/src/plugins/builtin/market-valuation/index.tsx +64 -0
  243. package/src/plugins/builtin/market-valuation/indicators.ts +422 -0
  244. package/src/plugins/builtin/market-valuation/model.test.ts +350 -0
  245. package/src/plugins/builtin/market-valuation/model.ts +8 -0
  246. package/src/plugins/builtin/market-valuation/pane.test.tsx +247 -0
  247. package/src/plugins/builtin/market-valuation/pane.tsx +344 -0
  248. package/src/plugins/builtin/market-valuation/series.ts +12 -0
  249. package/src/plugins/builtin/market-valuation/settings.ts +38 -0
  250. package/src/plugins/builtin/market-valuation/sources.ts +130 -0
  251. package/src/plugins/builtin/market-valuation/trend.ts +89 -0
  252. package/src/plugins/builtin/market-valuation/view.ts +137 -0
  253. package/src/plugins/builtin/market-valuation/zone-scale/desktop.tsx +123 -0
  254. package/src/plugins/builtin/market-valuation/zone-scale/index.tsx +12 -0
  255. package/src/plugins/builtin/market-valuation/zone-scale/model.ts +60 -0
  256. package/src/plugins/builtin/market-valuation/zone-scale/terminal.tsx +94 -0
  257. package/src/plugins/builtin/news/wire/breaking/filters.test.ts +99 -0
  258. package/src/plugins/builtin/news/wire/breaking/filters.ts +110 -0
  259. package/src/plugins/builtin/news/wire/breaking/notifications.test.ts +157 -53
  260. package/src/plugins/builtin/news/wire/breaking/notifications.ts +91 -25
  261. package/src/plugins/builtin/news/wire/index.tsx +31 -44
  262. package/src/plugins/builtin/options/analytics.test.ts +83 -0
  263. package/src/plugins/builtin/options/analytics.ts +110 -0
  264. package/src/plugins/builtin/options/index.tsx +18 -2
  265. package/src/plugins/builtin/options/table.ts +121 -51
  266. package/src/plugins/builtin/options/types.ts +22 -15
  267. package/src/plugins/builtin/options/view.test.tsx +53 -1
  268. package/src/plugins/builtin/options/view.tsx +92 -41
  269. package/src/plugins/builtin/plugin-marketplace/feed.ts +80 -0
  270. package/src/plugins/builtin/plugin-marketplace/index.tsx +31 -0
  271. package/src/plugins/builtin/plugin-marketplace/model.test.ts +200 -0
  272. package/src/plugins/builtin/plugin-marketplace/model.ts +204 -0
  273. package/src/plugins/builtin/plugin-marketplace/pane.tsx +385 -0
  274. package/src/plugins/builtin/plugin-marketplace/store.ts +46 -0
  275. package/src/plugins/builtin/plugin-module.test.ts +2 -4
  276. package/src/plugins/builtin/plugin-module.ts +9 -8
  277. package/src/plugins/builtin/portfolio-list/index.tsx +1 -0
  278. package/src/plugins/builtin/research/index.tsx +4 -0
  279. package/src/plugins/builtin/research-search/command-bar-search.test.ts +81 -0
  280. package/src/plugins/builtin/research-search/command-bar-search.ts +175 -0
  281. package/src/plugins/builtin/research-search/data.ts +109 -0
  282. package/src/plugins/builtin/research-search/document-view.test.tsx +75 -0
  283. package/src/plugins/builtin/research-search/document-view.tsx +254 -0
  284. package/src/plugins/builtin/research-search/filter-bar.tsx +62 -0
  285. package/src/plugins/builtin/research-search/focus-handoff.ts +47 -0
  286. package/src/plugins/builtin/research-search/index.tsx +85 -0
  287. package/src/plugins/builtin/research-search/model.test.ts +40 -0
  288. package/src/plugins/builtin/research-search/model.ts +291 -0
  289. package/src/plugins/builtin/research-search/pane.test.tsx +241 -0
  290. package/src/plugins/builtin/research-search/pane.tsx +678 -0
  291. package/src/plugins/builtin/research-search/saved-view.tsx +171 -0
  292. package/src/plugins/builtin/research-search/snippet-text.tsx +35 -0
  293. package/src/plugins/builtin/research-search/snippet.test.ts +78 -0
  294. package/src/plugins/builtin/research-search/snippet.ts +134 -0
  295. package/src/plugins/builtin/scanner/flow-model.test.ts +11 -1
  296. package/src/plugins/builtin/scanner/flow-model.ts +29 -1
  297. package/src/plugins/builtin/scanner/flow-pane.tsx +78 -22
  298. package/src/plugins/builtin/scanner/index.ts +2 -0
  299. package/src/plugins/builtin/sec/index.tsx +1 -0
  300. package/src/plugins/builtin/sectors/index.tsx +1 -0
  301. package/src/plugins/builtin/shared/series-cache.ts +93 -0
  302. package/src/plugins/builtin/short-interest/index.tsx +1 -0
  303. package/src/plugins/builtin/short-interest/pane.tsx +1 -1
  304. package/src/plugins/builtin/thirteenf/index.tsx +1 -0
  305. package/src/plugins/builtin/ticker-detail/data-panes/historical-prices.tsx +3 -5
  306. package/src/plugins/builtin/ticker-detail/index.tsx +2 -14
  307. package/src/plugins/builtin/ticker-detail/overview-tab.tsx +1 -1
  308. package/src/plugins/builtin/treasury-auctions/index.tsx +1 -0
  309. package/src/plugins/builtin/volatility/index.tsx +1 -1
  310. package/src/plugins/builtin/world-indices/index.tsx +1 -0
  311. package/src/plugins/builtin/world-venue-map/index.ts +27 -0
  312. package/src/plugins/builtin/world-venue-map/map.desktop.test.tsx +106 -0
  313. package/src/plugins/builtin/world-venue-map/map.tsx +481 -0
  314. package/src/plugins/builtin/world-venue-map/model.test.ts +85 -0
  315. package/src/plugins/builtin/world-venue-map/model.ts +268 -0
  316. package/src/plugins/builtin/world-venue-map/pane.tsx +300 -0
  317. package/src/plugins/builtin/world-venue-map/world-outlines.ts +2 -0
  318. package/src/plugins/builtin/yield-curve/index.tsx +1 -1
  319. package/src/plugins/bundle.test.ts +109 -0
  320. package/src/plugins/bundle.ts +139 -0
  321. package/src/plugins/catalog-backend.ts +6 -44
  322. package/src/plugins/catalog-browser.test.ts +1 -0
  323. package/src/plugins/catalog-browser.ts +12 -0
  324. package/src/plugins/catalog-manifest.test.ts +43 -0
  325. package/src/plugins/catalog-manifest.ts +92 -0
  326. package/src/plugins/catalog-ui.ts +20 -4
  327. package/src/plugins/catalog.ts +9 -2
  328. package/src/plugins/current-target.ts +28 -0
  329. package/src/plugins/host-contract.ts +37 -0
  330. package/src/plugins/host-link.ts +158 -0
  331. package/src/plugins/host-modules.ts +61 -0
  332. package/src/plugins/loader.ts +41 -22
  333. package/src/plugins/ownership.ts +1 -0
  334. package/src/plugins/prediction-markets/index.tsx +1 -0
  335. package/src/plugins/registry/context.ts +3 -0
  336. package/src/plugins/registry/contributions.ts +27 -0
  337. package/src/plugins/registry/index.test.ts +25 -0
  338. package/src/plugins/registry/index.ts +8 -0
  339. package/src/plugins/registry/pane-settings.test.ts +53 -0
  340. package/src/plugins/registry/pane-settings.ts +29 -3
  341. package/src/plugins/seed.test.ts +83 -0
  342. package/src/plugins/seed.ts +80 -0
  343. package/src/public/broker.ts +31 -0
  344. package/src/public/market-data.ts +9 -0
  345. package/src/public/pane-hooks.ts +57 -0
  346. package/src/public/public-api.test.ts +285 -0
  347. package/src/public/react.ts +62 -0
  348. package/src/public/test-support.ts +23 -0
  349. package/src/public/time-series.ts +8 -0
  350. package/src/public/utils.ts +77 -0
  351. package/src/remote/layout-helpers.ts +6 -8
  352. package/src/remote/resources.ts +2 -0
  353. package/src/remote/schema.ts +1 -0
  354. package/src/remote/semantic-tree.test.tsx +105 -0
  355. package/src/remote/semantic-tree.tsx +53 -35
  356. package/src/renderers/browser/main.tsx +6 -0
  357. package/src/renderers/browser/ui-host.tsx +11 -0
  358. package/src/renderers/cloudflare/worker.test.ts +19 -0
  359. package/src/renderers/cloudflare/worker.ts +1 -1
  360. package/src/renderers/electrobun/bun/desktop/host-requests.ts +9 -2
  361. package/src/renderers/electrobun/bun/external-plugins.ts +140 -0
  362. package/src/renderers/electrobun/bun/index.ts +6 -2
  363. package/src/renderers/electrobun/shared/protocol.ts +25 -0
  364. package/src/renderers/electrobun/view/build-assets.ts +0 -1
  365. package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +51 -1
  366. package/src/renderers/electrobun/view/external-plugins.test.ts +45 -0
  367. package/src/renderers/electrobun/view/external-plugins.ts +63 -0
  368. package/src/renderers/electrobun/view/host/ascii-text.test.ts +48 -0
  369. package/src/renderers/electrobun/view/host/ascii-text.ts +11 -1
  370. package/src/renderers/electrobun/view/host/chart-surface.tsx +38 -32
  371. package/src/renderers/electrobun/view/host/mouse.ts +16 -2
  372. package/src/renderers/electrobun/view/main.tsx +27 -2
  373. package/src/renderers/electrobun/view/styles.css +5 -0
  374. package/src/renderers/electrobun/view/toast-host.tsx +18 -0
  375. package/src/renderers/electrobun/view/ui-host.tsx +3 -0
  376. package/src/renderers/opentui/chart-surface.tsx +5 -1
  377. package/src/renderers/opentui/host.tsx +20 -2
  378. package/src/renderers/opentui/interaction-performance.test.ts +79 -0
  379. package/src/renderers/opentui/interaction-performance.ts +188 -0
  380. package/src/renderers/opentui/start.tsx +26 -1
  381. package/src/renderers/opentui/test-utils.tsx +13 -0
  382. package/src/renderers/opentui/toast-host.tsx +26 -2
  383. package/src/renderers/opentui/ui-host.tsx +1 -0
  384. package/src/sources/provider-router/search.test.ts +191 -0
  385. package/src/sources/provider-router/search.ts +92 -39
  386. package/src/state/app/context/index.tsx +2 -0
  387. package/src/state/app/context/selector.test.tsx +33 -1
  388. package/src/state/hooks/quote-streaming.test.tsx +93 -0
  389. package/src/state/hooks/quote-streaming.ts +106 -30
  390. package/src/state/pane-table-export-registry.ts +50 -0
  391. package/src/theme/color-utils.ts +1 -1
  392. package/src/theme/colors.ts +50 -0
  393. package/src/theme/themes.test.ts +15 -2
  394. package/src/theme/themes.ts +19 -1
  395. package/src/tickers/search/index.test.ts +26 -0
  396. package/src/tickers/search/index.ts +42 -17
  397. package/src/tickers/search/ranking.ts +14 -0
  398. package/src/time-series/chart-data.test.ts +216 -0
  399. package/src/time-series/range.ts +12 -0
  400. package/src/time-series/resolution.test.ts +25 -26
  401. package/src/time-series/resolution.ts +44 -25
  402. package/src/time-series/resolve.ts +7 -0
  403. package/src/time-series/spec.ts +5 -5
  404. package/src/time-series/types.ts +3 -1
  405. package/src/time-series/use-chart-resolution.ts +5 -0
  406. package/src/types/config.ts +123 -3
  407. package/src/types/data-provider.ts +11 -0
  408. package/src/types/headless.ts +161 -0
  409. package/src/types/plugin.ts +104 -20
  410. package/src/ui/host.tsx +19 -1
  411. package/src/ui/index.tsx +1 -0
  412. package/src/ui/toast.tsx +8 -4
  413. package/src/utils/csv.test.ts +13 -0
  414. package/src/utils/csv.ts +37 -0
  415. package/src/utils/format.ts +35 -0
  416. package/src/utils/fuzzy-search.test.ts +94 -0
  417. package/src/utils/fuzzy-search.ts +81 -22
  418. package/src/utils/save-text-file.test.ts +24 -0
  419. package/src/utils/save-text-file.ts +36 -0
  420. package/src/utils/shortcut-labels.ts +14 -0
  421. package/src/components/chart/core/axis-format.ts +0 -157
  422. package/src/components/chart/core/index.test.ts +0 -1075
  423. package/src/components/chart/core/projection.ts +0 -357
  424. package/src/components/chart/core/render-utils.ts +0 -4
  425. package/src/components/chart/core/renderer.ts +0 -244
  426. package/src/components/chart/core/scene.ts +0 -180
  427. package/src/components/chart/core/time-axis.ts +0 -330
  428. package/src/components/chart/cursor-motion.ts +0 -47
  429. package/src/components/chart/indicators/types.ts +0 -26
  430. package/src/components/chart/market-session.ts +0 -176
  431. package/src/components/chart/multi-line/renderer.test.ts +0 -83
  432. package/src/components/chart/multi-line/renderer.ts +0 -161
  433. package/src/components/chart/multi-line/scene.ts +0 -188
  434. package/src/components/chart/native/raster/layout.ts +0 -129
  435. package/src/components/chart/native/raster/price-chart.ts +0 -244
  436. package/src/components/chart/rendering/chart-draw.ts +0 -270
  437. package/src/components/chart/rendering/geometry.ts +0 -95
  438. package/src/components/chart/rendering/pixel-buffer.ts +0 -267
  439. package/src/components/chart/scatter-chart-renderer.test.ts +0 -31
  440. package/src/components/chart/scatter-chart-renderer.ts +0 -223
  441. package/src/components/chart/static/chart/surface.tsx +0 -358
  442. package/src/components/command-bar/routes/root/article-results.test.ts +0 -83
  443. package/src/components/command-bar/routes/root/article-results.ts +0 -55
  444. package/src/plugins/builtin/news/wire/article-search.test.ts +0 -72
  445. package/src/plugins/builtin/news/wire/article-search.ts +0 -140
  446. package/src/plugins/builtin/substack/api/auth.ts +0 -185
  447. package/src/plugins/builtin/substack/api/cache.ts +0 -82
  448. package/src/plugins/builtin/substack/api/loaders.ts +0 -170
  449. package/src/plugins/builtin/substack/api/store.ts +0 -186
  450. package/src/plugins/builtin/substack/api/types.ts +0 -42
  451. package/src/plugins/builtin/substack/api.test.ts +0 -298
  452. package/src/plugins/builtin/substack/article-detail.tsx +0 -397
  453. package/src/plugins/builtin/substack/article-stack.tsx +0 -133
  454. package/src/plugins/builtin/substack/content.ts +0 -478
  455. package/src/plugins/builtin/substack/feed-tabs.tsx +0 -44
  456. package/src/plugins/builtin/substack/index.tsx +0 -49
  457. package/src/plugins/builtin/substack/login-view.tsx +0 -126
  458. package/src/plugins/builtin/substack/model.test.ts +0 -155
  459. package/src/plugins/builtin/substack/normalize.ts +0 -343
  460. package/src/plugins/builtin/substack/pane-footer.ts +0 -52
  461. package/src/plugins/builtin/substack/pane-state.ts +0 -170
  462. package/src/plugins/builtin/substack/pane.tsx +0 -547
  463. package/src/plugins/builtin/substack/read-state.ts +0 -30
  464. package/src/plugins/builtin/substack/table.ts +0 -111
  465. package/src/plugins/builtin/substack/types.ts +0 -71
  466. package/src/plugins/builtin/substack/utils.ts +0 -131
  467. package/src/plugins/builtin/ticker-detail/data-panes/provider-search.tsx +0 -229
  468. package/src/plugins/ibkr/account-cache.test.ts +0 -102
  469. package/src/plugins/ibkr/account-cache.ts +0 -24
  470. package/src/plugins/ibkr/broker-adapter.ts +0 -286
  471. package/src/plugins/ibkr/config.test.ts +0 -79
  472. package/src/plugins/ibkr/config.ts +0 -250
  473. package/src/plugins/ibkr/dialogs.tsx +0 -40
  474. package/src/plugins/ibkr/flex/index.test.ts +0 -264
  475. package/src/plugins/ibkr/flex/index.ts +0 -367
  476. package/src/plugins/ibkr/flex/statement-client.ts +0 -235
  477. package/src/plugins/ibkr/fundamental-parser.ts +0 -149
  478. package/src/plugins/ibkr/gateway/account-loaders.ts +0 -266
  479. package/src/plugins/ibkr/gateway/account-summary.ts +0 -164
  480. package/src/plugins/ibkr/gateway/client-lock.ts +0 -154
  481. package/src/plugins/ibkr/gateway/connection-events.ts +0 -114
  482. package/src/plugins/ibkr/gateway/connection.ts +0 -152
  483. package/src/plugins/ibkr/gateway/contracts.ts +0 -132
  484. package/src/plugins/ibkr/gateway/fundamentals.ts +0 -83
  485. package/src/plugins/ibkr/gateway/helpers.ts +0 -33
  486. package/src/plugins/ibkr/gateway/history-requests.ts +0 -158
  487. package/src/plugins/ibkr/gateway/history.ts +0 -120
  488. package/src/plugins/ibkr/gateway/instrument-lookup.ts +0 -117
  489. package/src/plugins/ibkr/gateway/market-data.ts +0 -345
  490. package/src/plugins/ibkr/gateway/order-execution.ts +0 -218
  491. package/src/plugins/ibkr/gateway/orders.ts +0 -63
  492. package/src/plugins/ibkr/gateway/price-normalization.test.ts +0 -44
  493. package/src/plugins/ibkr/gateway/price-normalization.ts +0 -50
  494. package/src/plugins/ibkr/gateway/quote-stream-controller.ts +0 -203
  495. package/src/plugins/ibkr/gateway/quote-stream.ts +0 -171
  496. package/src/plugins/ibkr/gateway/selection.ts +0 -51
  497. package/src/plugins/ibkr/gateway/service/index.test.ts +0 -675
  498. package/src/plugins/ibkr/gateway/service/index.ts +0 -429
  499. package/src/plugins/ibkr/gateway/service/lifecycle.ts +0 -191
  500. package/src/plugins/ibkr/gateway/service/manager.ts +0 -52
  501. package/src/plugins/ibkr/gateway/service/market-data.ts +0 -48
  502. package/src/plugins/ibkr/gateway/service/native-loader.ts +0 -12
  503. package/src/plugins/ibkr/gateway/service/native.ts +0 -543
  504. package/src/plugins/ibkr/gateway/timeouts.ts +0 -13
  505. package/src/plugins/ibkr/gateway/types.ts +0 -27
  506. package/src/plugins/ibkr/index.test.tsx +0 -162
  507. package/src/plugins/ibkr/index.tsx +0 -159
  508. package/src/plugins/ibkr/instance-selection.test.ts +0 -120
  509. package/src/plugins/ibkr/instance-selection.ts +0 -36
  510. package/src/plugins/ibkr/portfolio-performance.test.ts +0 -32
  511. package/src/plugins/ibkr/portfolio-performance.ts +0 -129
  512. package/src/plugins/ibkr/trade/badge.tsx +0 -28
  513. package/src/plugins/ibkr/trade/dialogs.tsx +0 -44
  514. package/src/plugins/ibkr/trade/preview-panel.tsx +0 -130
  515. package/src/plugins/ibkr/trade/tab/actions.tsx +0 -443
  516. package/src/plugins/ibkr/trade/tab/field-editors.tsx +0 -79
  517. package/src/plugins/ibkr/trade/tab/footer.ts +0 -53
  518. package/src/plugins/ibkr/trade/tab/header.tsx +0 -167
  519. package/src/plugins/ibkr/trade/tab/index.test.tsx +0 -178
  520. package/src/plugins/ibkr/trade/tab/index.tsx +0 -298
  521. package/src/plugins/ibkr/trade/tab/model.ts +0 -159
  522. package/src/plugins/ibkr/trade/tab/order-request.ts +0 -64
  523. package/src/plugins/ibkr/trade/tab/shortcuts.ts +0 -89
  524. package/src/plugins/ibkr/trade/tab/state-sync.ts +0 -86
  525. package/src/plugins/ibkr/trade/ticket-panel.tsx +0 -301
  526. package/src/plugins/ibkr/trade/utils.test.ts +0 -175
  527. package/src/plugins/ibkr/trade/utils.ts +0 -144
  528. package/src/plugins/ibkr/trading/pane-view.tsx +0 -237
  529. package/src/plugins/ibkr/trading/pane.tsx +0 -332
  530. package/src/plugins/ibkr/trading/state.test.ts +0 -109
  531. package/src/plugins/ibkr/trading/state.ts +0 -335
@@ -9,7 +9,9 @@ import { CloudApiSocket } from "./socket";
9
9
  import type {
10
10
  CloudCdsParams,
11
11
  CloudCongressHouseParams,
12
+ CloudEarningsCallsParams,
12
13
  CloudFredSeriesParams,
14
+ CloudSearchParams,
13
15
  CloudSecFilingParams,
14
16
  CloudSecFilingsParams,
15
17
  CloudHistoryParams,
@@ -48,9 +50,19 @@ import type {
48
50
  CloudEquityDiagnosticResult,
49
51
  CloudCdsResponse,
50
52
  CloudFredSeriesPayload,
53
+ CloudShillerPayload,
51
54
  CloudYieldPointPayload,
52
55
  CloudCongressHousePayload,
56
+ CloudEarningsCallListPayload,
57
+ CloudEarningsTranscriptPayload,
53
58
  CloudNewsPayload,
59
+ CloudSavedSearch,
60
+ CloudSavedSearchInput,
61
+ CloudSearchDocType,
62
+ CloudSearchDocument,
63
+ CloudSearchDocumentResponse,
64
+ CloudSearchHit,
65
+ CloudSearchResponse,
54
66
  CloudSecContentResponse,
55
67
  CloudSecDocumentsResponse,
56
68
  CloudSecFilingsResponse,
@@ -61,6 +73,7 @@ import type {
61
73
  CloudMarketBatchPayload,
62
74
  CloudMarketScreenerCategory,
63
75
  CloudMarketScreenerPayload,
76
+ CloudWorldVenueMapPayload,
64
77
  CloudVerificationResponse,
65
78
  DeviceAuthStartResponse,
66
79
  DeviceAuthTokenResponse,
@@ -91,6 +104,8 @@ const ASSIST_REQUEST_TIMEOUT_MS = 6_000;
91
104
  class GloomApiClient {
92
105
  private currentUser: AuthUser | null = null;
93
106
  private sessionChecked = false;
107
+ /** Last few session transitions, content-free, for app://auth. */
108
+ private authTrace: Array<{ at: number; event: string; token: boolean; user: string }> = [];
94
109
  private sessionRequest: Promise<AuthUser | null> | null = null;
95
110
  private readonly currentUserListeners = new Set<() => void>();
96
111
  private readonly transport = new CloudApiRequestTransport();
@@ -153,6 +168,7 @@ class GloomApiClient {
153
168
  const changed = this.transport.getSessionToken() !== token;
154
169
  this.sessionChecked = false;
155
170
  this.transport.setSessionToken(token);
171
+ this.traceAuth(changed ? "setSessionToken:changed" : "setSessionToken:same");
156
172
  if (!token) {
157
173
  this.currentUser = null;
158
174
  this.emitCurrentUserChange();
@@ -195,8 +211,58 @@ class GloomApiClient {
195
211
  return this.transport.hasSessionCredential() && !!this.currentUser?.emailVerified;
196
212
  }
197
213
 
214
+ /**
215
+ * What this client currently believes about its session, with no secrets.
216
+ * Exposed over remote control so a "shows my username but not my
217
+ * subscription" report can be answered from the running app instead of
218
+ * from guesses about it.
219
+ */
220
+ describeAuthState(): {
221
+ hasSessionCredential: boolean;
222
+ hasSessionToken: boolean;
223
+ sessionChecked: boolean;
224
+ sessionRequestInFlight: boolean;
225
+ trace: Array<{ at: number; event: string; token: boolean; user: string }>;
226
+ currentUser: {
227
+ id: string;
228
+ emailVerified: boolean;
229
+ plan: string | null;
230
+ effectivePlan: string | null;
231
+ trialEndsAt: string | null;
232
+ } | null;
233
+ } {
234
+ const user = this.currentUser;
235
+ return {
236
+ hasSessionCredential: this.transport.hasSessionCredential(),
237
+ hasSessionToken: !!this.transport.getSessionToken(),
238
+ sessionChecked: this.sessionChecked,
239
+ sessionRequestInFlight: !!this.sessionRequest,
240
+ trace: [...this.authTrace],
241
+ currentUser: user
242
+ ? {
243
+ id: user.id,
244
+ emailVerified: user.emailVerified === true,
245
+ plan: user.plan ?? null,
246
+ effectivePlan: user.effectivePlan ?? null,
247
+ trialEndsAt: user.trialEndsAt ?? null,
248
+ }
249
+ : null,
250
+ };
251
+ }
252
+
253
+ private traceAuth(event: string, user: AuthUser | null = this.currentUser): void {
254
+ this.authTrace.push({
255
+ at: Date.now(),
256
+ event,
257
+ token: !!this.transport.getSessionToken(),
258
+ user: user ? (user.emailVerified ? "verified" : "unverified") : "none",
259
+ });
260
+ if (this.authTrace.length > 24) this.authTrace.shift();
261
+ }
262
+
198
263
  private setCurrentUser(user: AuthUser | null): void {
199
264
  const changed = this.socketEntitlementKey(this.currentUser) !== this.socketEntitlementKey(user);
265
+ this.traceAuth("setCurrentUser", user);
200
266
  this.currentUser = user;
201
267
  this.socket.syncAuthState({ reconnect: changed });
202
268
  this.emitCurrentUserChange();
@@ -264,12 +330,20 @@ class GloomApiClient {
264
330
  }
265
331
 
266
332
  async getSession(): Promise<AuthUser | null> {
267
- if (this.sessionRequest) return this.sessionRequest;
333
+ if (this.sessionRequest) {
334
+ this.traceAuth("getSession:joined-inflight");
335
+ return this.sessionRequest;
336
+ }
337
+ this.traceAuth("getSession:start");
268
338
  this.sessionRequest = this.auth.getSession();
269
339
  try {
270
340
  const user = await this.sessionRequest;
271
341
  this.sessionChecked = true;
342
+ this.traceAuth("getSession:done", user);
272
343
  return user;
344
+ } catch (error) {
345
+ this.traceAuth(`getSession:error:${error instanceof Error ? error.message.slice(0, 60) : "unknown"}`);
346
+ throw error;
273
347
  } finally {
274
348
  this.sessionRequest = null;
275
349
  }
@@ -545,6 +619,10 @@ class GloomApiClient {
545
619
  return this.data.getCloudQuotesBatch(targets, mode);
546
620
  }
547
621
 
622
+ async getCloudWorldVenues(): Promise<CloudMarketResponse<CloudWorldVenueMapPayload>> {
623
+ return this.data.getCloudWorldVenues();
624
+ }
625
+
548
626
  async getCloudMarketScreener(
549
627
  category: CloudMarketScreenerCategory,
550
628
  count = 25,
@@ -635,6 +713,10 @@ class GloomApiClient {
635
713
  return this.data.getCloudFredSeries(seriesId, params);
636
714
  }
637
715
 
716
+ async getCloudShiller(): Promise<CloudShillerPayload> {
717
+ return this.data.getCloudShiller();
718
+ }
719
+
638
720
  async getCloudYieldCurve(): Promise<CloudYieldPointPayload[]> {
639
721
  return this.data.getCloudYieldCurve();
640
722
  }
@@ -647,6 +729,16 @@ class GloomApiClient {
647
729
  return this.data.getCloudCongressHouse(params);
648
730
  }
649
731
 
732
+ async getCloudEarningsCalls(
733
+ params: CloudEarningsCallsParams = {},
734
+ ): Promise<CloudEarningsCallListPayload> {
735
+ return this.data.getCloudEarningsCalls(params);
736
+ }
737
+
738
+ async getCloudEarningsTranscript(id: string): Promise<CloudEarningsTranscriptPayload> {
739
+ return this.data.getCloudEarningsTranscript(id);
740
+ }
741
+
650
742
  async getCloudSecFilings(params: CloudSecFilingsParams): Promise<CloudSecFilingsResponse> {
651
743
  return this.data.getCloudSecFilings(params);
652
744
  }
@@ -663,6 +755,47 @@ class GloomApiClient {
663
755
  return this.data.getCloudSec13F(path, params);
664
756
  }
665
757
 
758
+ async searchCloudDocuments(
759
+ params: CloudSearchParams,
760
+ options?: { signal?: AbortSignal },
761
+ ): Promise<CloudSearchResponse> {
762
+ return this.data.searchCloudDocuments(params, options);
763
+ }
764
+
765
+ async getCloudSearchDocument(
766
+ docType: CloudSearchDocType,
767
+ sourceId: string,
768
+ options?: { signal?: AbortSignal },
769
+ ): Promise<CloudSearchDocument> {
770
+ return this.data.getCloudSearchDocument(docType, sourceId, options);
771
+ }
772
+
773
+ async getCloudSavedSearches(options?: { signal?: AbortSignal }): Promise<CloudSavedSearch[]> {
774
+ return this.data.getCloudSavedSearches(options);
775
+ }
776
+
777
+ async createCloudSavedSearch(input: CloudSavedSearchInput): Promise<CloudSavedSearch> {
778
+ return this.data.createCloudSavedSearch(input);
779
+ }
780
+
781
+ async updateCloudSavedSearch(
782
+ id: string,
783
+ update: Partial<CloudSavedSearchInput>,
784
+ ): Promise<CloudSavedSearch> {
785
+ return this.data.updateCloudSavedSearch(id, update);
786
+ }
787
+
788
+ async deleteCloudSavedSearch(id: string): Promise<void> {
789
+ return this.data.deleteCloudSavedSearch(id);
790
+ }
791
+
792
+ async getCloudSavedSearchHits(
793
+ id: string,
794
+ options?: { signal?: AbortSignal },
795
+ ): Promise<CloudSearchHit[]> {
796
+ return this.data.getCloudSavedSearchHits(id, options);
797
+ }
798
+
666
799
  async getCloudNews(params: CloudNewsParams = {}): Promise<CloudNewsListResponse> {
667
800
  return this.data.getCloudNews(params);
668
801
  }
@@ -3,11 +3,50 @@ import type {
3
3
  ChatMessage,
4
4
  ChatNotification,
5
5
  ChatStateResponse,
6
+ CloudSavedSearch,
7
+ CloudSearchHit,
8
+ CloudSearchResponse,
6
9
  CloudTweetPayload,
7
10
  CloudTweetSearchResponse,
8
11
  } from "./types";
9
12
  import { normalizeTimestamp } from "../utils/timestamp";
10
13
 
14
+ /**
15
+ * Saved-search writes answer with either the record itself or `{ search }`.
16
+ * Both shapes are accepted so a server-side envelope change cannot silently
17
+ * hand the pane an object with no `id`.
18
+ */
19
+ export function normalizeSavedSearchResponse(response: unknown): CloudSavedSearch {
20
+ const envelope = response as { search?: CloudSavedSearch } | CloudSavedSearch | null;
21
+ const search = envelope && "search" in envelope && envelope.search
22
+ ? envelope.search
23
+ : envelope as CloudSavedSearch | null;
24
+ if (!search?.id) throw new Error("The saved search response was missing a record.");
25
+ return search;
26
+ }
27
+
28
+ export function normalizeSavedSearchHits(response: unknown): CloudSearchHit[] {
29
+ const hits = (response as { hits?: unknown } | null)?.hits;
30
+ return Array.isArray(hits) ? (hits as CloudSearchHit[]).map(normalizeSearchHit) : [];
31
+ }
32
+
33
+ /**
34
+ * A wire story or filing need not name an issuer, and the server sends `ticker:
35
+ * null` when it does not. Coerced to an empty string at the boundary so the
36
+ * declared `string` is true of every hit: consumers test it for truthiness,
37
+ * join it into search text, and hand it to a badge, and a null reaches each of
38
+ * those as an empty chip, the literal "null", or a crash.
39
+ */
40
+ export function normalizeSearchHit(hit: CloudSearchHit): CloudSearchHit {
41
+ return hit.ticker ? hit : { ...hit, ticker: "" };
42
+ }
43
+
44
+ export function normalizeSearchResponse(response: CloudSearchResponse): CloudSearchResponse {
45
+ const hits = response.hits;
46
+ if (!Array.isArray(hits)) return { ...response, hits: [] };
47
+ return { ...response, hits: hits.map(normalizeSearchHit) };
48
+ }
49
+
11
50
  export function normalizeChatMessage(message: ChatMessage): ChatMessage {
12
51
  return {
13
52
  ...message,
@@ -1,4 +1,4 @@
1
- import type { CloudTweetQueryType } from "./types";
1
+ import type { CloudSearchDocType, CloudSearchSort, CloudTweetQueryType } from "./types";
2
2
  import { normalizeSymbol, publicTickerKey } from "../utils/exchanges";
3
3
 
4
4
  export type CloudHistoryParams = {
@@ -34,6 +34,14 @@ export type CloudCongressHouseParams = {
34
34
  refresh?: boolean;
35
35
  };
36
36
 
37
+ export type CloudEarningsCallsParams = {
38
+ ticker?: string;
39
+ limit?: number;
40
+ offset?: number;
41
+ /** Include calls still working through the transcription pipeline. */
42
+ includePending?: boolean;
43
+ };
44
+
37
45
  export type CloudNewsParams = {
38
46
  feed?: "latest" | "top" | "breaking" | "ticker" | "sector" | "topic";
39
47
  ticker?: string;
@@ -131,6 +139,10 @@ export function cloudHistoryPath(symbol: string, exchange: string, params: Cloud
131
139
  return appendQuery("/market/history", search);
132
140
  }
133
141
 
142
+ export function cloudShillerPath(): string {
143
+ return "/cloud/econ/shiller";
144
+ }
145
+
134
146
  export function cloudExchangeRatePath(fromCurrency: string): string {
135
147
  return appendQuery("/market/exchange-rate", new URLSearchParams({ fromCurrency }));
136
148
  }
@@ -181,6 +193,19 @@ export function cloudCongressHousePath(params: CloudCongressHouseParams = {}): s
181
193
  return appendQuery("/cloud/congress/house", search);
182
194
  }
183
195
 
196
+ export function cloudEarningsCallsPath(params: CloudEarningsCallsParams = {}): string {
197
+ const search = new URLSearchParams();
198
+ if (params.ticker) search.set("ticker", params.ticker);
199
+ if (params.limit != null) search.set("limit", String(params.limit));
200
+ if (params.offset != null) search.set("offset", String(params.offset));
201
+ if (params.includePending) search.set("includePending", "true");
202
+ return appendQuery("/cloud/transcripts", search);
203
+ }
204
+
205
+ export function cloudEarningsTranscriptPath(id: string): string {
206
+ return `/cloud/transcripts/${encodeURIComponent(id)}`;
207
+ }
208
+
184
209
  export function cloudSecFilingsPath(params: CloudSecFilingsParams): string {
185
210
  const search = new URLSearchParams({ ticker: params.ticker });
186
211
  if (params.limit != null) search.set("limit", String(params.limit));
@@ -218,6 +243,65 @@ export function cloudSec13FPath(path: string, params: Record<string, string | nu
218
243
  return appendQuery(`/cloud/sec/13f/${normalized}`, search);
219
244
  }
220
245
 
246
+ export type CloudSearchParams = {
247
+ query: string;
248
+ tickers?: readonly string[];
249
+ docTypes?: readonly CloudSearchDocType[];
250
+ sources?: readonly string[];
251
+ /** Inclusive ISO date or timestamp bounds on `publishedAt`. */
252
+ from?: string;
253
+ to?: string;
254
+ sort?: CloudSearchSort;
255
+ limit?: number;
256
+ offset?: number;
257
+ /** Set false to skip the total-count pass when only the top hits are shown. */
258
+ count?: boolean;
259
+ /** One row per source document instead of one per matching chunk. */
260
+ distinct?: boolean;
261
+ };
262
+
263
+ function csvParam(values: readonly string[] | undefined): string | null {
264
+ if (!values) return null;
265
+ const cleaned = values.map((value) => value.trim()).filter((value) => value.length > 0);
266
+ return cleaned.length > 0 ? cleaned.join(",") : null;
267
+ }
268
+
269
+ export function cloudSearchPath(params: CloudSearchParams): string {
270
+ const search = new URLSearchParams({ q: params.query.trim() });
271
+ const tickers = csvParam(params.tickers?.map(normalizeSymbol));
272
+ if (tickers) search.set("tickers", tickers);
273
+ const docTypes = csvParam(params.docTypes);
274
+ if (docTypes) search.set("docTypes", docTypes);
275
+ const sources = csvParam(params.sources);
276
+ if (sources) search.set("sources", sources);
277
+ if (params.from) search.set("from", params.from);
278
+ if (params.to) search.set("to", params.to);
279
+ if (params.sort) search.set("sort", params.sort);
280
+ if (params.limit != null) search.set("limit", String(params.limit));
281
+ // Offset 0 is the default page, so sending it only lengthens the cache key.
282
+ if (params.offset) search.set("offset", String(params.offset));
283
+ // Counting is the server default, so only opting out is worth a parameter.
284
+ if (params.count === false) search.set("count", "false");
285
+ if (params.distinct) search.set("distinct", "true");
286
+ return appendQuery("/cloud/search", search);
287
+ }
288
+
289
+ export function cloudSearchDocumentPath(docType: CloudSearchDocType, sourceId: string): string {
290
+ return `/cloud/search/documents/${encodeURIComponent(docType)}/${encodeURIComponent(sourceId)}`;
291
+ }
292
+
293
+ export function cloudSavedSearchesPath(): string {
294
+ return "/cloud/search/saved";
295
+ }
296
+
297
+ export function cloudSavedSearchPath(id: string): string {
298
+ return `/cloud/search/saved/${encodeURIComponent(id)}`;
299
+ }
300
+
301
+ export function cloudSavedSearchHitsPath(id: string): string {
302
+ return `${cloudSavedSearchPath(id)}/hits`;
303
+ }
304
+
221
305
  export function cloudNewsPath(params: CloudNewsParams = {}): string {
222
306
  const search = new URLSearchParams();
223
307
  if (params.feed) search.set("feed", params.feed);
@@ -253,6 +253,30 @@ export interface CloudQuotePayload extends Quote {
253
253
  dataSource: "live" | "delayed";
254
254
  }
255
255
 
256
+ export interface CloudWorldVenuePayload {
257
+ mic: string;
258
+ name: string;
259
+ title: string;
260
+ country: string;
261
+ countryCode: string;
262
+ city: string;
263
+ timezone: string;
264
+ latitude: number;
265
+ longitude: number;
266
+ isOpen: boolean;
267
+ timeAfterOpenSeconds?: number;
268
+ timeToOpenSeconds?: number;
269
+ timeToCloseSeconds?: number;
270
+ }
271
+
272
+ export interface CloudWorldVenueMapPayload {
273
+ providerId: "gloomberb-cloud";
274
+ checkedAt: number;
275
+ refreshAt: number;
276
+ stale?: boolean;
277
+ venues: CloudWorldVenuePayload[];
278
+ }
279
+
256
280
  export interface CloudOptionsChainPayload extends OptionsChain {
257
281
  providerId: "gloomberb-cloud";
258
282
  }
@@ -322,6 +346,28 @@ export interface CloudFredSeriesPayload {
322
346
  info: CloudFredSeriesInfoPayload | null;
323
347
  }
324
348
 
349
+ /**
350
+ * One month of Robert Shiller's dataset. FRED carries no long-run S&P earnings,
351
+ * so this is what every earnings-based valuation ratio is built from.
352
+ */
353
+ export interface CloudShillerObservationPayload {
354
+ date: string;
355
+ price: number | null;
356
+ dividend: number | null;
357
+ earnings: number | null;
358
+ cpi: number | null;
359
+ longRate: number | null;
360
+ cape: number | null;
361
+ /** CAPE earnings yield over the real 10-year rate; Shiller's equity risk premium. */
362
+ excessCapeYield: number | null;
363
+ }
364
+
365
+ export interface CloudShillerPayload {
366
+ observations: CloudShillerObservationPayload[];
367
+ sourceUrl: string;
368
+ fetchedAt: string;
369
+ }
370
+
325
371
  /** One publicly disseminated single-name CDS transaction report. */
326
372
  export interface CloudCdsTradePayload {
327
373
  disseminationId: string;
@@ -442,6 +488,180 @@ export interface CloudCongressHousePayload {
442
488
  members: CloudCongressMemberPayload[];
443
489
  }
444
490
 
491
+ export interface CloudEarningsCallPayload {
492
+ id: string;
493
+ ticker: string;
494
+ companyName: string | null;
495
+ fiscalYear: number | null;
496
+ fiscalQuarter: number | null;
497
+ callAt: string | null;
498
+ status: string;
499
+ durationSeconds: number | null;
500
+ wordCount: number | null;
501
+ hasTranscript: boolean;
502
+ sentiment: number | null;
503
+ /** The replay or event page the transcript came from. */
504
+ webcastUrl?: string | null;
505
+ }
506
+
507
+ export interface CloudEarningsCallListPayload {
508
+ calls: CloudEarningsCallPayload[];
509
+ /** Set when asking about a company started a search that is still running. */
510
+ pending?: boolean;
511
+ /** Set when the requested symbol is not one the SEC knows. */
512
+ unknownTicker?: boolean;
513
+ }
514
+
515
+ export interface CloudTranscriptTurnPayload {
516
+ speaker: string;
517
+ role?: string;
518
+ company?: string;
519
+ text: string;
520
+ isQa: boolean;
521
+ startSeconds: number;
522
+ }
523
+
524
+ export interface CloudTranscriptParticipantPayload {
525
+ name: string;
526
+ role?: string;
527
+ company?: string;
528
+ }
529
+
530
+ export interface CloudEarningsTranscriptPayload {
531
+ id: string;
532
+ ticker: string;
533
+ companyName: string | null;
534
+ fiscalYear: number | null;
535
+ fiscalQuarter: number | null;
536
+ callAt: string | null;
537
+ timing: string | null;
538
+ webcastUrl: string | null;
539
+ durationSeconds: number | null;
540
+ status: string;
541
+ fullText: string;
542
+ turns: CloudTranscriptTurnPayload[];
543
+ participants: CloudTranscriptParticipantPayload[];
544
+ summary: string | null;
545
+ guidance: string | null;
546
+ riskFactors: string | null;
547
+ analystFocus: string | null;
548
+ notable: string | null;
549
+ sentiment: number | null;
550
+ sentimentRationale: string | null;
551
+ qaStartTurn: number | null;
552
+ wordCount: number | null;
553
+ asrModel: string | null;
554
+ updatedAt: string | null;
555
+ }
556
+
557
+ export type CloudSearchDocType = "transcript" | "news" | "filing";
558
+
559
+ export type CloudSearchSort = "relevance" | "newest" | "oldest";
560
+
561
+ /**
562
+ * Per-chunk provenance. Which keys are present depends on `docType`: transcripts
563
+ * carry speaker attribution, news carries the wire source, filings carry the
564
+ * form and section. Kept as one optional-key record so an unknown docType from a
565
+ * newer server still renders instead of failing to parse.
566
+ */
567
+ export interface CloudSearchChunkMetadata {
568
+ speaker?: string;
569
+ role?: string;
570
+ company?: string;
571
+ isQa?: boolean;
572
+ startSeconds?: number;
573
+ turnIndex?: number;
574
+ source?: string;
575
+ summary?: string;
576
+ form?: string;
577
+ accession?: string;
578
+ section?: string;
579
+ }
580
+
581
+ export interface CloudSearchHit {
582
+ id: string;
583
+ docType: CloudSearchDocType;
584
+ sourceId: string;
585
+ chunkIndex: number;
586
+ ticker: string;
587
+ publishedAt: string;
588
+ title: string;
589
+ url: string;
590
+ /** Matched terms wrapped in `<mark>`, fragments joined by an ellipsis. */
591
+ snippet: string;
592
+ score: number;
593
+ metadata: CloudSearchChunkMetadata;
594
+ /**
595
+ * Chunks of this document that matched. Only sent for a distinct search,
596
+ * where the row stands for the document rather than for one chunk.
597
+ */
598
+ matchCount?: number;
599
+ }
600
+
601
+ export interface CloudSearchResponse {
602
+ hits: CloudSearchHit[];
603
+ total: number;
604
+ /** The server stopped counting past its cap, so `total` is a lower bound. */
605
+ countCapped: boolean;
606
+ hasMore: boolean;
607
+ nextOffset: number;
608
+ tookMs: number;
609
+ }
610
+
611
+ export interface CloudSearchDocumentChunk {
612
+ id: string;
613
+ chunkIndex: number;
614
+ body: string;
615
+ metadata: CloudSearchChunkMetadata;
616
+ }
617
+
618
+ export interface CloudSearchDocument {
619
+ docType: CloudSearchDocType;
620
+ sourceId: string;
621
+ ticker: string;
622
+ title: string;
623
+ url: string;
624
+ publishedAt: string;
625
+ chunks: CloudSearchDocumentChunk[];
626
+ }
627
+
628
+ export interface CloudSearchDocumentResponse {
629
+ document: CloudSearchDocument;
630
+ }
631
+
632
+ export interface CloudSavedSearchFilters {
633
+ tickers?: string[];
634
+ docTypes?: CloudSearchDocType[];
635
+ sources?: string[];
636
+ from?: string;
637
+ to?: string;
638
+ }
639
+
640
+ export interface CloudSavedSearch {
641
+ id: string;
642
+ name: string;
643
+ query: string;
644
+ filters: CloudSavedSearchFilters;
645
+ alertEnabled: boolean;
646
+ alertChannels: string[];
647
+ lastRunAt: string | null;
648
+ lastMatchAt: string | null;
649
+ matchCount: number;
650
+ createdAt: string;
651
+ }
652
+
653
+ export interface CloudSavedSearchListResponse {
654
+ searches: CloudSavedSearch[];
655
+ }
656
+
657
+ export interface CloudSavedSearchInput {
658
+ name: string;
659
+ query: string;
660
+ filters?: CloudSavedSearchFilters;
661
+ alertEnabled?: boolean;
662
+ alertChannels?: string[];
663
+ }
664
+
445
665
  export interface CloudSecFilingPayload {
446
666
  accessionNumber: string;
447
667
  form: string;