gloomberb 0.15.6 → 0.15.8

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 (311) hide show
  1. package/README.md +3 -2
  2. package/README.zh-CN.md +1 -1
  3. package/package.json +1 -1
  4. package/src/api-client/data.ts +42 -10
  5. package/src/api-client/doe.ts +75 -0
  6. package/src/api-client/estimate-revisions.ts +1 -1
  7. package/src/api-client/futures-curve.ts +1 -1
  8. package/src/api-client/index.ts +7 -0
  9. package/src/api-client/market-discovery.ts +84 -0
  10. package/src/api-client/paths.ts +17 -11
  11. package/src/api-client/request.ts +12 -2
  12. package/src/api-client/tape.ts +2 -2
  13. package/src/api-client/types.ts +4 -0
  14. package/src/app/dialog-bridge.tsx +33 -0
  15. package/src/app/pane-runtime/index.tsx +7 -2
  16. package/src/app/pane-runtime/pane-settings-runtime.tsx +2 -1
  17. package/src/app/pane-runtime/pane-template-runtime.ts +8 -28
  18. package/src/app/pane-runtime/plugin-bindings.ts +34 -12
  19. package/src/app/pane-runtime/ticker-open-runtime.ts +5 -3
  20. package/src/app/runtime/broker-import.ts +1 -1
  21. package/src/app/runtime/desktop-menu.ts +9 -6
  22. package/src/app/runtime/plugin-bindings.ts +7 -1
  23. package/src/app/runtime/ticker-refresh.ts +1 -1
  24. package/src/app.tsx +12 -0
  25. package/src/brokers/directory.ts +11 -2
  26. package/src/brokers/profile-form.ts +2 -1
  27. package/src/brokers/remove-profile.ts +61 -0
  28. package/src/brokers/signed-in/connect.ts +20 -7
  29. package/src/brokers/signed-in/sign-in-dialog.tsx +68 -30
  30. package/src/cli/desktop-pane-shot.ts +2 -2
  31. package/src/cli/history-rows.ts +1 -1
  32. package/src/cli/pane-functions/function-help.ts +18 -3
  33. package/src/cli/ticker-resolution.ts +2 -2
  34. package/src/components/chart/composite/composite-chart.tsx +15 -2
  35. package/src/components/chart/composite/format.ts +24 -11
  36. package/src/components/chart/composite/rasterizer.ts +67 -16
  37. package/src/components/chart/composite/scene.ts +53 -2
  38. package/src/components/chart/composite/session-shading.ts +3 -2
  39. package/src/components/chart/composite/text-renderer.ts +52 -1
  40. package/src/components/chart/composite/time-axis.ts +100 -30
  41. package/src/components/chart/composite/tools.ts +2 -1
  42. package/src/components/chart/composite/types.ts +4 -0
  43. package/src/components/command-bar/action-runtime.ts +7 -67
  44. package/src/components/command-bar/commands/direct/index.ts +9 -5
  45. package/src/components/command-bar/commands/direct/runtime.ts +12 -11
  46. package/src/components/command-bar/commands/plugin/actions.ts +6 -35
  47. package/src/components/command-bar/helpers.ts +3 -31
  48. package/src/components/command-bar/keyboard-handlers.ts +7 -219
  49. package/src/components/command-bar/keyboard-shortcuts.ts +25 -99
  50. package/src/components/command-bar/layout-items/current-layout.ts +2 -1
  51. package/src/components/command-bar/layout-items/focused-pane.ts +2 -1
  52. package/src/components/command-bar/layout-items/types.ts +2 -0
  53. package/src/components/command-bar/layout-items.ts +3 -0
  54. package/src/components/command-bar/list/model.ts +1 -1
  55. package/src/components/command-bar/list/navigation.ts +5 -12
  56. package/src/components/command-bar/pane-actions.ts +17 -14
  57. package/src/components/command-bar/pane-settings.ts +7 -250
  58. package/src/components/command-bar/pane-templates/workflow.ts +6 -13
  59. package/src/components/command-bar/panel/index.tsx +4 -110
  60. package/src/components/command-bar/panel/layout.ts +4 -16
  61. package/src/components/command-bar/panel/runtime.ts +1 -87
  62. package/src/components/command-bar/panel/state.ts +12 -29
  63. package/src/components/command-bar/panel/types.ts +2 -26
  64. package/src/components/command-bar/picker-activation.ts +7 -56
  65. package/src/components/command-bar/routes/root/plugin-install.ts +3 -3
  66. package/src/components/command-bar/routes/root/search-report.ts +2 -1
  67. package/src/components/command-bar/routing/actions.ts +21 -59
  68. package/src/components/command-bar/routing/confirm.ts +15 -88
  69. package/src/components/command-bar/routing/effects.ts +1 -20
  70. package/src/components/command-bar/routing/launch-request.ts +1 -36
  71. package/src/components/command-bar/routing/list-state.ts +5 -36
  72. package/src/components/command-bar/selection-runtime.ts +6 -35
  73. package/src/components/command-bar/surface/environment.ts +10 -6
  74. package/src/components/command-bar/surface/index.tsx +4 -37
  75. package/src/components/command-bar/workflow/alert.ts +23 -17
  76. package/src/components/command-bar/workflow/broker.ts +30 -40
  77. package/src/components/command-bar/workflow/builtin.ts +33 -38
  78. package/src/components/command-bar/workflow/collection-actions.ts +27 -28
  79. package/src/components/command-bar/workflow/collection-ticker.ts +4 -4
  80. package/src/components/command-bar/workflow/coordinator.ts +27 -156
  81. package/src/components/command-bar/workflow/fields.ts +6 -22
  82. package/src/components/command-bar/workflow/submit.ts +28 -43
  83. package/src/components/command-bar/workflow/ticker-listing-picker.ts +12 -9
  84. package/src/components/command-bar/workflow/tickers.ts +2 -2
  85. package/src/components/command-bar/workflow/types.ts +10 -35
  86. package/src/components/feedback-dialog.tsx +1 -13
  87. package/src/components/form-modal/broker-step.tsx +119 -0
  88. package/src/components/form-modal/confirm.tsx +145 -0
  89. package/src/components/form-modal/content.tsx +698 -0
  90. package/src/components/form-modal/deps.ts +77 -0
  91. package/src/components/form-modal/field-row.tsx +318 -0
  92. package/src/components/form-modal/host.tsx +169 -0
  93. package/src/components/form-modal/index.ts +2 -0
  94. package/src/components/form-modal/model.ts +131 -0
  95. package/src/components/form-modal/request.ts +67 -0
  96. package/src/components/form-modal/routes.ts +139 -0
  97. package/src/components/layout/shell/index.tsx +49 -28
  98. package/src/components/layout/status-bar.tsx +2 -1
  99. package/src/components/onboarding/first-run-workspace.ts +1 -1
  100. package/src/components/onboarding/onboarding-frame.tsx +4 -1
  101. package/src/components/onboarding/onboarding-wizard.tsx +1 -1
  102. package/src/components/onboarding/portfolio-step/positions-panel.tsx +14 -5
  103. package/src/components/onboarding/wizard-model.ts +13 -5
  104. package/src/components/onboarding/wizard-positions.ts +56 -7
  105. package/src/components/pane-settings-dialog.tsx +7 -1
  106. package/src/components/pane-template-wizard.tsx +4 -149
  107. package/src/components/sign-in-code-panel.tsx +22 -9
  108. package/src/components/textarea-keys.ts +13 -0
  109. package/src/components/ui/button.tsx +3 -2
  110. package/src/components/ui/confirm-dialog.tsx +62 -10
  111. package/src/components/ui/display.tsx +6 -3
  112. package/src/components/ui/fields.tsx +5 -0
  113. package/src/components/ui/frame.tsx +7 -2
  114. package/src/components/ui/header-case.ts +25 -3
  115. package/src/components/ui/list-view.tsx +16 -9
  116. package/src/components/ui/query-bar.tsx +8 -1
  117. package/src/core/app-runtime.ts +1 -1
  118. package/src/core/state/app/types.ts +1 -15
  119. package/src/data/config/home.ts +82 -11
  120. package/src/data/config/store/node.ts +29 -16
  121. package/src/i18n/es.ts +54 -7
  122. package/src/i18n/ja.ts +54 -7
  123. package/src/i18n/ko.ts +54 -7
  124. package/src/i18n/zh-cn.ts +54 -7
  125. package/src/i18n/zh-tw.ts +54 -7
  126. package/src/layout-marketplace/gallery.tsx +11 -3
  127. package/src/market-data/coordinator/fx-legs.ts +1 -1
  128. package/src/market-data/history-session.ts +3 -5
  129. package/src/market-data/market/freshness.ts +1 -1
  130. package/src/market-data/market/status.ts +1 -1
  131. package/src/market-data/market/trading-sessions.ts +65 -1
  132. package/src/market-data/quotes/metadata.ts +3 -3
  133. package/src/market-data/quotes/resolution.ts +3 -3
  134. package/src/news/types.ts +1 -1
  135. package/src/plugins/builtin/alerts/alert-engine.ts +2 -0
  136. package/src/plugins/builtin/alerts/cli.ts +2 -2
  137. package/src/plugins/builtin/alerts/types.ts +2 -0
  138. package/src/plugins/builtin/broker-manager/add-flow.tsx +625 -0
  139. package/src/plugins/builtin/broker-manager/add-request.ts +34 -0
  140. package/src/plugins/builtin/broker-manager/detail.tsx +128 -50
  141. package/src/plugins/builtin/broker-manager/footer.ts +6 -5
  142. package/src/plugins/builtin/broker-manager/index.tsx +62 -21
  143. package/src/plugins/builtin/broker-manager/model.ts +7 -0
  144. package/src/plugins/builtin/broker-manager/pane-actions.tsx +47 -44
  145. package/src/plugins/builtin/chart-composer/cli-options.ts +4 -0
  146. package/src/plugins/builtin/chart-composer/headless-schema.ts +6 -0
  147. package/src/plugins/builtin/chart-composer/pane.tsx +28 -1
  148. package/src/plugins/builtin/cloud/company-picker.tsx +658 -0
  149. package/src/plugins/builtin/composite-plugins.ts +2 -0
  150. package/src/plugins/builtin/credit-boards/model.ts +1 -1
  151. package/src/plugins/builtin/dividend-yield/browser.tsx +2 -25
  152. package/src/plugins/builtin/dividend-yield/client.ts +34 -122
  153. package/src/plugins/builtin/dividend-yield/index.tsx +9 -9
  154. package/src/plugins/builtin/dividend-yield/provider-client.ts +1 -1
  155. package/src/plugins/builtin/doe/client.ts +73 -0
  156. package/src/plugins/builtin/doe/headless.ts +93 -0
  157. package/src/plugins/builtin/doe/index.tsx +41 -0
  158. package/src/plugins/builtin/doe/model.ts +215 -0
  159. package/src/plugins/builtin/doe/pane.tsx +148 -0
  160. package/src/plugins/builtin/doe/range-bar.tsx +45 -0
  161. package/src/plugins/builtin/earnings-calls/transcript-view.tsx +7 -7
  162. package/src/plugins/builtin/estimate-revisions/client.ts +3 -3
  163. package/src/plugins/builtin/estimate-revisions/pane.tsx +2 -2
  164. package/src/plugins/builtin/executives/pane.tsx +17 -8
  165. package/src/plugins/builtin/fear-greed/charts.tsx +1 -1
  166. package/src/plugins/builtin/filing-events/pane.tsx +23 -6
  167. package/src/plugins/builtin/futures/contracts.ts +3 -3
  168. package/src/plugins/builtin/futures/returns.ts +1 -1
  169. package/src/plugins/builtin/futures-curve/client.ts +1 -1
  170. package/src/plugins/builtin/futures-curve/model.ts +1 -1
  171. package/src/plugins/builtin/help/index.tsx +8 -3
  172. package/src/plugins/builtin/holders/pane.tsx +1 -1
  173. package/src/plugins/builtin/kelly-sizer/pane.tsx +1 -1
  174. package/src/plugins/builtin/market-heatmap/data.ts +13 -256
  175. package/src/plugins/builtin/market-heatmap/index.tsx +5 -15
  176. package/src/plugins/builtin/market-movers/client.ts +1 -1
  177. package/src/plugins/builtin/market-movers/screener.ts +60 -142
  178. package/src/plugins/builtin/market-valuation/defs.ts +1 -2
  179. package/src/plugins/builtin/market-valuation/sources.ts +1 -3
  180. package/src/plugins/builtin/news/wire/default-feeds.ts +2 -8
  181. package/src/plugins/builtin/news/wire/feed-config.ts +5 -1
  182. package/src/plugins/builtin/news/wire/persisted-articles.ts +9 -5
  183. package/src/plugins/builtin/news/wire/rss/cli.ts +1 -1
  184. package/src/plugins/builtin/news/wire/rss/managed-feed.ts +19 -0
  185. package/src/plugins/builtin/news/wire/rss/parser.ts +18 -9
  186. package/src/plugins/builtin/news/wire/rss/source.ts +1 -1
  187. package/src/plugins/builtin/options/view.tsx +1 -1
  188. package/src/plugins/builtin/plugin-marketplace/model.ts +5 -0
  189. package/src/plugins/builtin/plugin-marketplace/pane.tsx +4 -2
  190. package/src/plugins/builtin/portfolio-list/cli/render.ts +1 -1
  191. package/src/plugins/builtin/portfolio-list/cli/watchlist-command.ts +6 -20
  192. package/src/plugins/builtin/portfolio-list/command-bar.ts +6 -2
  193. package/src/plugins/builtin/portfolio-list/mutations.ts +53 -1
  194. package/src/plugins/builtin/relative-rotation/client.ts +1 -1
  195. package/src/plugins/builtin/research/analyst-model.ts +1 -1
  196. package/src/plugins/builtin/research/equity-diagnostic-pane.tsx +6 -6
  197. package/src/plugins/builtin/research/event-model.ts +1 -1
  198. package/src/plugins/builtin/risk-factors/pane.tsx +29 -14
  199. package/src/plugins/builtin/shared/pro-feature-wall.tsx +47 -0
  200. package/src/plugins/builtin/shared/ticker-request.ts +1 -1
  201. package/src/plugins/builtin/short-interest/client.ts +14 -106
  202. package/src/plugins/builtin/short-interest/headless.ts +2 -2
  203. package/src/plugins/builtin/short-interest/index.tsx +5 -5
  204. package/src/plugins/builtin/short-interest/pane.tsx +4 -4
  205. package/src/plugins/builtin/ticker-detail/financials/ratios.ts +42 -10
  206. package/src/plugins/builtin/ticker-detail/overview-tab.tsx +1 -1
  207. package/src/plugins/builtin/ticker-detail/pane.tsx +2 -2
  208. package/src/plugins/builtin/ticker-detail/quote-monitor/card.tsx +1 -1
  209. package/src/plugins/builtin/time-sales/client.ts +3 -3
  210. package/src/plugins/builtin/vol-surface/model.ts +1 -1
  211. package/src/plugins/builtin/volatility/model.ts +1 -1
  212. package/src/plugins/bundle.ts +2 -2
  213. package/src/plugins/catalog-browser.ts +2 -0
  214. package/src/plugins/catalog-manifest.ts +0 -1
  215. package/src/plugins/catalog-ui.ts +1 -1
  216. package/src/plugins/catalog.ts +0 -2
  217. package/src/plugins/host-link.ts +1 -1
  218. package/src/plugins/host-resolver.ts +1 -1
  219. package/src/plugins/loader.ts +6 -5
  220. package/src/plugins/registry/host-actions.ts +6 -1
  221. package/src/plugins/registry/index.ts +1 -0
  222. package/src/plugins/runtime/context.tsx +2 -0
  223. package/src/plugins/runtime/index.tsx +2 -0
  224. package/src/public/__snapshots__/public-api.test.ts.snap +0 -1
  225. package/src/public/market-data.ts +0 -7
  226. package/src/remote/controller-utils.ts +1 -1
  227. package/src/remote/controller.ts +27 -3
  228. package/src/remote/form.ts +20 -0
  229. package/src/remote/resources.ts +7 -0
  230. package/src/remote/schema.ts +25 -3
  231. package/src/remote/semantic-tree.tsx +15 -0
  232. package/src/remote/types.ts +2 -0
  233. package/src/renderers/browser/research-entry.ts +2 -2
  234. package/src/renderers/cloudflare/http-proxy.ts +157 -33
  235. package/src/renderers/cloudflare/proxy-session.ts +270 -0
  236. package/src/renderers/cloudflare/worker.ts +4 -1
  237. package/src/renderers/dom/desktop/controls.tsx +2 -1
  238. package/src/renderers/dom/dialog-host.tsx +17 -8
  239. package/src/renderers/dom/styles.css +4 -0
  240. package/src/renderers/electrobun/bun/application-menu/index.ts +4 -4
  241. package/src/renderers/electrobun/bun/desktop/backend.ts +7 -1
  242. package/src/renderers/electrobun/bun/desktop/initialization.ts +2 -2
  243. package/src/renderers/electrobun/bun/external-plugins.ts +1 -1
  244. package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +3 -6
  245. package/src/renderers/electrobun/view/cli-pane-shot-health.ts +3 -3
  246. package/src/renderers/opentui/dialog-host.tsx +14 -2
  247. package/src/renderers/opentui/start.tsx +2 -2
  248. package/src/renderers/opentui/terminal-media.ts +2 -2
  249. package/src/renderers/opentui/test-utils.tsx +9 -2
  250. package/src/renderers/opentui/toast-host.tsx +1 -1
  251. package/src/sources/gloomberb-cloud/index.ts +70 -37
  252. package/src/sources/gloomberb-cloud/news.ts +3 -3
  253. package/src/sources/history-result.ts +1 -0
  254. package/src/sources/history-retention.ts +22 -6
  255. package/src/sources/{yahoo-finance/symbols.ts → listing-symbols.ts} +16 -41
  256. package/src/sources/listing-target.ts +4 -4
  257. package/src/sources/provider-router/cache.ts +16 -6
  258. package/src/sources/provider-router/financials.ts +1 -1
  259. package/src/sources/provider-router/history.ts +7 -4
  260. package/src/state/app/bootstrap.ts +1 -1
  261. package/src/state/app/context/index.tsx +13 -0
  262. package/src/sync/core-contributors.ts +181 -18
  263. package/src/test-support/plugin-runtime.ts +1 -0
  264. package/src/tickers/instrument-kind.ts +1 -1
  265. package/src/tickers/open-target.ts +5 -5
  266. package/src/tickers/search/index.ts +46 -13
  267. package/src/tickers/search/ranking.ts +4 -4
  268. package/src/tickers/search/upsert.ts +4 -1
  269. package/src/time-series/live-bars.ts +8 -3
  270. package/src/time-series/resolution.ts +1 -1
  271. package/src/time-series/resolve.ts +225 -18
  272. package/src/time-series/spec.ts +1 -0
  273. package/src/time-series/types.ts +9 -1
  274. package/src/types/data-provider.ts +2 -0
  275. package/src/types/financials.ts +5 -5
  276. package/src/types/instrument.ts +1 -1
  277. package/src/types/plugin.ts +3 -3
  278. package/src/types/price-history.ts +3 -1
  279. package/src/ui/dialog-bridge.tsx +50 -0
  280. package/src/ui/dialog-context.ts +24 -0
  281. package/src/ui/dialog-stack.ts +47 -1
  282. package/src/ui/dialog.tsx +2 -10
  283. package/src/ui/host.tsx +6 -1
  284. package/src/ui/index.tsx +7 -2
  285. package/src/utils/exchanges.ts +1 -0
  286. package/src/utils/latest-financial-period.ts +1 -1
  287. package/src/utils/plugin-proxy-hosts.json +1 -5
  288. package/src/utils/price-history.ts +35 -1
  289. package/src/utils/sec.ts +3 -2
  290. package/src/utils/zoned-date-time.ts +67 -0
  291. package/src/app/pane-template-dialog-wizard.tsx +0 -67
  292. package/src/components/command-bar/multi-select-picker.tsx +0 -225
  293. package/src/components/command-bar/multi-select-runtime.ts +0 -91
  294. package/src/components/command-bar/workflow/body.tsx +0 -164
  295. package/src/components/command-bar/workflow/field-row.tsx +0 -231
  296. package/src/components/command-bar/workflow/route-actions.ts +0 -235
  297. package/src/components/command-bar/workflow/runtime.ts +0 -247
  298. package/src/plugins/builtin/yahoo/index.ts +0 -38
  299. package/src/sources/yahoo-finance/chart-period.ts +0 -138
  300. package/src/sources/yahoo-finance/financials.ts +0 -370
  301. package/src/sources/yahoo-finance/history.ts +0 -150
  302. package/src/sources/yahoo-finance/http.ts +0 -119
  303. package/src/sources/yahoo-finance/mappers.ts +0 -549
  304. package/src/sources/yahoo-finance/names.ts +0 -28
  305. package/src/sources/yahoo-finance/options.ts +0 -190
  306. package/src/sources/yahoo-finance/quote-summary.ts +0 -176
  307. package/src/sources/yahoo-finance/requests.ts +0 -245
  308. package/src/sources/yahoo-finance/snapshots.ts +0 -336
  309. package/src/sources/yahoo-finance/types.ts +0 -198
  310. package/src/sources/yahoo-finance/yahoo-chart-interval.ts +0 -18
  311. package/src/sources/yahoo-finance.ts +0 -339
package/README.md CHANGED
@@ -38,7 +38,7 @@ The desktop app and TUI share the command language and plugin system. The [brows
38
38
  On **macOS (Apple Silicon)**:
39
39
 
40
40
  ```bash
41
- brew install --cask vincelwt/tap/gloomberb
41
+ brew install --cask gloomberb
42
42
  ```
43
43
 
44
44
  On **Windows 11**, [download the installer](https://github.com/gloom-sh/gloomberb/releases/latest/download/stable-win-x64-GloomberbSetup.exe). It supports x64, and ARM64 through x64 emulation.
@@ -76,6 +76,7 @@ Press `Ctrl+P` to open the command bar, or press `` ` `` to search for a ticker.
76
76
  | `HVG AAPL` / `HVT AAPL` | Realized volatility and volatility cones |
77
77
  | `SEAS AAPL` | Seasonality: monthly returns by year and year overlays |
78
78
  | `COT [code or root]` | CFTC positioning and cross-market extremes |
79
+ | `DOE` / `NGS` | EIA weekly oil stocks and gas storage, with builds, draws and five-year ranges |
79
80
  | `TOP` | Market stories |
80
81
  | `WIRP` / `FFIP` | US rate path and conditional FOMC probabilities |
81
82
  | `BTMM` | Funding rates, bill curves and Federal Reserve liquidity |
@@ -117,7 +118,7 @@ When the app hits an uncaught error, a render crash, or a plugin that fails to l
117
118
 
118
119
  The app also counts how often you open each function, from the command bar, a menu or a link in another pane, and which functions are on screen when a workspace is restored at launch. It sends each function's mnemonic (such as `DES` or `GP`) with those two counts, the surface, the app version and the operating system, a minute after the first count, then every 15 minutes, and when you quit. Functions from plugins other than the official gloom-sh ones are sent as `plugin`, so their names never leave your machine. The server adds your plan (signed out, Free or Pro); the counts are never tied to your account.
119
120
 
120
- Neither contains anything from your workspace: no tickers, arguments, portfolios, watchlists, layouts, settings or queries. Both carry a random install id stored in `~/.gloomberb/install-id` (in the browser, in local storage).
121
+ Neither contains anything from your workspace: no tickers, arguments, portfolios, watchlists, layouts, settings or queries. Both carry a random install id stored in `install-id` in the data folder, `~/.gloomberb` by default (in the browser, in local storage).
121
122
 
122
123
  The usage setting also covers command bar searches. When you are signed in, a search you finish in the command bar (you pause typing or run something, never each keystroke) is stored with your account to improve search: its text, the AI suggestions it got and the result you picked. Searches are deleted with your account.
123
124
 
package/README.zh-CN.md CHANGED
@@ -40,7 +40,7 @@
40
40
  在 **macOS(Apple Silicon)** 上:
41
41
 
42
42
  ```bash
43
- brew install --cask vincelwt/tap/gloomberb
43
+ brew install --cask gloomberb
44
44
  ```
45
45
 
46
46
  在 **Windows 11** 上,[下载安装程序](https://github.com/gloom-sh/gloomberb/releases/latest/download/stable-win-x64-GloomberbSetup.exe)。支持 x64,也可通过 x64 仿真在 ARM64 上运行。
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gloomberb",
3
- "version": "0.15.6",
3
+ "version": "0.15.8",
4
4
  "packageManager": "bun@1.3.11",
5
5
  "description": "Market research and portfolio tracker for the terminal",
6
6
  "module": "src/public/index.ts",
@@ -1,3 +1,5 @@
1
+ import type { EarningsEvent } from "../types/data-provider";
2
+ import type { MarketDividendsPayload, MarketHeatmapResult, MarketHeatmapUniverseId, MarketMoversPayload } from "./market-discovery";
1
3
  import type { DebtMaturitiesPayload } from "./debt-maturities";
2
4
  import type { RevenueBreakdownPayload, RevenueBreakdownView } from "./revenue-breakdown";
3
5
  import type { MnaDealPayload, MnaDealsParams, MnaDealsPayload } from "./mna";
@@ -12,6 +14,7 @@ import type { ShortVolumePayload, ShortVolumeScope } from "./short-volume";
12
14
  import type { SocialMentionDayPosts, SocialMentionsPayload, SocialMentionsRange } from "./social-mentions";
13
15
  import type { FuturesCurveAsOfPayload, FuturesCurvePayload } from "./futures-curve";
14
16
  import type { CotBoardPayload, CotContractPayload, CotFamily, CotClass } from "./cot";
17
+ import type { DoeBoardPayload } from "./doe";
15
18
  import type { TapeSnapshot } from "./tape";
16
19
  import type { ExchangeRateSnapshot } from "../types/exchange-rate";
17
20
  import type { RatePathPayload } from "./rates";
@@ -39,11 +42,11 @@ import {
39
42
  cloudJobsPath,
40
43
  cloudJobsPostingsPath,
41
44
  type CloudJobsPostingsParams,
42
- publicProxyStatementPath,
43
- publicFilingEventsPath,
44
- publicRiskReportPath,
45
- publicRiskReportsPath,
46
- publicProxyStatementsPath,
45
+ cloudProxyStatementPath,
46
+ cloudFilingEventsPath,
47
+ cloudRiskReportPath,
48
+ cloudRiskReportsPath,
49
+ cloudProxyStatementsPath,
47
50
  cloudExchangeRatePath,
48
51
  cloudSec13FPath,
49
52
  cloudSecFilingContentPath,
@@ -213,6 +216,31 @@ export class CloudDataApi {
213
216
  );
214
217
  }
215
218
 
219
+ getMarketEarningsCalendar(symbols: string[]): Promise<CloudMarketResponse<Array<Omit<EarningsEvent, "earningsDate" | "earningsCallDate"> & { earningsDate: string; earningsCallDate?: string | null }>>> {
220
+ return this.request(`/market/earnings-calendar?${new URLSearchParams({ symbols: symbols.join(",") })}`);
221
+ }
222
+
223
+ getCloudArticleSummary(url: string): Promise<{ summary: string | null }> {
224
+ return this.request(`/news/article-summary?${new URLSearchParams({ url })}`);
225
+ }
226
+
227
+ getMarketMovers(category: "day_gainers" | "day_losers" | "most_actives", count = 25, refresh = false): Promise<CloudMarketResponse<MarketMoversPayload>> {
228
+ const params = new URLSearchParams({ category, count: String(count), mode: refresh ? "refresh" : "cache-first" });
229
+ return this.request(`/market/movers?${params}`);
230
+ }
231
+
232
+ getMarketTrending(count = 25): Promise<CloudMarketResponse<Array<{ symbol: string }>>> {
233
+ return this.request(`/market/trending?count=${encodeURIComponent(count)}`);
234
+ }
235
+
236
+ getMarketHeatmap(universe: MarketHeatmapUniverseId, count = 80): Promise<CloudMarketResponse<MarketHeatmapResult>> {
237
+ return this.request(`/market/heatmap?${new URLSearchParams({ universe, count: String(count) })}`);
238
+ }
239
+
240
+ getMarketDividends(symbol: string, exchange = ""): Promise<CloudMarketResponse<MarketDividendsPayload>> {
241
+ return this.requestMarketSymbol("/market/dividends", symbol, exchange);
242
+ }
243
+
216
244
  /** Gainers, losers and most active, or the pre-market, after-hours and gap lists with a `side`. */
217
245
  async getCloudMarketScreener<Category extends CloudMarketScreenerCategory | CloudSessionMoversCategory>(
218
246
  category: Category,
@@ -358,6 +386,10 @@ export class CloudDataApi {
358
386
  return this.request<CotContractPayload>(`/cloud/cot/contracts/${encodeURIComponent(code)}?${new URLSearchParams({ report })}`);
359
387
  }
360
388
 
389
+ async getCloudDoeBoard(): Promise<DoeBoardPayload> {
390
+ return this.request<DoeBoardPayload>("/cloud/doe/board");
391
+ }
392
+
361
393
  async getCloudTape(symbol: string, exchange: string, signal?: AbortSignal): Promise<TapeSnapshot> {
362
394
  return this.request<TapeSnapshot>(`/cloud/tape/${encodeURIComponent(symbol)}?exchange=${encodeURIComponent(exchange)}`, { signal: signal ?? AbortSignal.timeout(30_000) });
363
395
  }
@@ -521,7 +553,7 @@ export class CloudDataApi {
521
553
  ticker: string,
522
554
  ): Promise<CloudProxyStatementListPayload> {
523
555
  return this.request<CloudProxyStatementListPayload>(
524
- publicProxyStatementsPath(ticker),
556
+ cloudProxyStatementsPath(ticker),
525
557
  );
526
558
  }
527
559
 
@@ -530,7 +562,7 @@ export class CloudDataApi {
530
562
  year: number,
531
563
  ): Promise<CloudProxyStatementPayload> {
532
564
  return this.request<CloudProxyStatementPayload>(
533
- publicProxyStatementPath(ticker, year),
565
+ cloudProxyStatementPath(ticker, year),
534
566
  );
535
567
  }
536
568
 
@@ -539,13 +571,13 @@ export class CloudDataApi {
539
571
  limit?: number,
540
572
  ): Promise<{ ticker: string; events: CloudFilingEventPayload[] }> {
541
573
  return this.request<{ ticker: string; events: CloudFilingEventPayload[] }>(
542
- publicFilingEventsPath(ticker, limit),
574
+ cloudFilingEventsPath(ticker, limit),
543
575
  );
544
576
  }
545
577
 
546
578
  async getRiskReports(ticker: string): Promise<CloudRiskReportListPayload> {
547
579
  return this.request<CloudRiskReportListPayload>(
548
- publicRiskReportsPath(ticker),
580
+ cloudRiskReportsPath(ticker),
549
581
  );
550
582
  }
551
583
 
@@ -554,7 +586,7 @@ export class CloudDataApi {
554
586
  year: number,
555
587
  ): Promise<CloudRiskReportPayload> {
556
588
  return this.request<CloudRiskReportPayload>(
557
- publicRiskReportPath(ticker, year),
589
+ cloudRiskReportPath(ticker, year),
558
590
  );
559
591
  }
560
592
 
@@ -0,0 +1,75 @@
1
+ /** EIA weekly petroleum and natural gas storage, as GET /cloud/doe/board serves it. */
2
+ export type DoeReport = "petroleum" | "gas";
3
+ export type DoeTab = "crude" | "products" | "gas";
4
+ /** Thousand barrels, thousand barrels a day, percent, billion cubic feet: as published. */
5
+ export type DoeUnit = "kb" | "kbd" | "pct" | "bcf";
6
+
7
+ interface DoeFiveYear {
8
+ /** Calendar years in the band, oldest first; fewer than five where history is short. */
9
+ years: number[];
10
+ min: number;
11
+ max: number;
12
+ average: number;
13
+ /** The average change into this week over the same years. */
14
+ averageChange: number | null;
15
+ vsAverage: number;
16
+ vsAveragePercent: number | null;
17
+ /** 0 at the five-year low, 100 at the high, beyond either outside the range. */
18
+ position: number | null;
19
+ }
20
+
21
+ interface DoeYearAgo {
22
+ weekEnding: string;
23
+ value: number;
24
+ change: number;
25
+ changePercent: number | null;
26
+ }
27
+
28
+ interface DoeSeasonal {
29
+ /** The calendar year of the latest week. */
30
+ year: number;
31
+ /** Fridays in that year: 52 or 53. */
32
+ weeks: number;
33
+ /** [week of year, value]. */
34
+ current: Array<[number, number]>;
35
+ previous: Array<[number, number]>;
36
+ /** [week, min, average, max] of the band years on that week's day. */
37
+ band: Array<[number, number | null, number | null, number | null]>;
38
+ }
39
+
40
+ export interface DoeSeriesRow {
41
+ id: string;
42
+ key: string;
43
+ report: DoeReport;
44
+ tab: DoeTab;
45
+ label: string;
46
+ unit: DoeUnit;
47
+ weekEnding: string | null;
48
+ value: number | null;
49
+ previousWeekEnding: string | null;
50
+ weekChange: number | null;
51
+ yearAgo: DoeYearAgo | null;
52
+ fiveYear: DoeFiveYear | null;
53
+ /** One plain read worked out from the numbers. */
54
+ read: string | null;
55
+ seasonal: DoeSeasonal | null;
56
+ }
57
+
58
+ export interface DoeReportStatus {
59
+ id: DoeReport;
60
+ weekEnding: string | null;
61
+ releasedAt: string | null;
62
+ releaseHoliday: string | null;
63
+ nextWeekEnding: string | null;
64
+ nextReleaseAt: string | null;
65
+ nextReleaseHoliday: string | null;
66
+ }
67
+
68
+ export interface DoeBoardPayload {
69
+ source: "EIA";
70
+ generatedAt: string;
71
+ status: "available" | "partial" | "unavailable";
72
+ gaps: string[];
73
+ reports: DoeReportStatus[];
74
+ series: DoeSeriesRow[];
75
+ }
@@ -22,7 +22,7 @@ export interface EstimateObservation {
22
22
  analysts: number | null;
23
23
  range: number | null;
24
24
  relativeRange: number | null;
25
- source: "yahoo" | "yahoo-eps-trend";
25
+ source: "gloom" | "gloom-eps-trend";
26
26
  }
27
27
  interface RevisionBreadth {
28
28
  days: 7 | 30;
@@ -22,7 +22,7 @@ export interface FuturesContract {
22
22
  export interface FuturesCurvePayload {
23
23
  root: string
24
24
  name: string
25
- source: "yahoo" | "cboe"
25
+ source: "gloom" | "cboe"
26
26
  currency: string | null
27
27
  quoteUnit: string | null
28
28
  asOf: string | null
@@ -677,6 +677,12 @@ class GloomApiClient {
677
677
  getCloudQuote = this.data.getCloudQuote.bind(this.data);
678
678
  getCloudQuotesBatch = this.data.getCloudQuotesBatch.bind(this.data);
679
679
  getCloudWorldVenues = this.data.getCloudWorldVenues.bind(this.data);
680
+ getMarketEarningsCalendar = this.data.getMarketEarningsCalendar.bind(this.data);
681
+ getCloudArticleSummary = this.data.getCloudArticleSummary.bind(this.data);
682
+ getMarketMovers = this.data.getMarketMovers.bind(this.data);
683
+ getMarketTrending = this.data.getMarketTrending.bind(this.data);
684
+ getMarketHeatmap = this.data.getMarketHeatmap.bind(this.data);
685
+ getMarketDividends = this.data.getMarketDividends.bind(this.data);
680
686
  getCloudMarketScreener = this.data.getCloudMarketScreener.bind(this.data);
681
687
  getCloudOptionsChain = this.data.getCloudOptionsChain.bind(this.data);
682
688
  getCloudFinancials = this.data.getCloudFinancials.bind(this.data);
@@ -715,6 +721,7 @@ class GloomApiClient {
715
721
  getCloudShiller = this.data.getCloudShiller.bind(this.data);
716
722
  getCloudCotBoard = this.data.getCloudCotBoard.bind(this.data);
717
723
  getCloudCotContract = this.data.getCloudCotContract.bind(this.data);
724
+ getCloudDoeBoard = this.data.getCloudDoeBoard.bind(this.data);
718
725
  getCloudTape = this.data.getCloudTape.bind(this.data);
719
726
  getCloudYieldCurve = this.data.getCloudYieldCurve.bind(this.data);
720
727
  getCloudCurve = this.data.getCloudCurve.bind(this.data);
@@ -0,0 +1,84 @@
1
+ import type { CloudCorporateActionsPayload, CloudQuotePayload } from "./types";
2
+
3
+ export interface ScreenerQuote {
4
+ symbol: string;
5
+ name: string;
6
+ price: number | null;
7
+ change: number | null;
8
+ changePercent: number | null;
9
+ volume: number | null;
10
+ avgVolume: number | null;
11
+ volumeRatio: number | null; // volume / avgVolume
12
+ marketCap: number | undefined;
13
+ currency: string;
14
+ fiftyTwoWeekHigh: number | undefined;
15
+ fiftyTwoWeekLow: number | undefined;
16
+ dayHigh: number | undefined;
17
+ dayLow: number | undefined;
18
+ exchange: string;
19
+ lastUpdated?: number;
20
+ /** Session-fixed, so the price column reads its decimals from it rather than from each tick. */
21
+ previousClose?: number;
22
+ }
23
+
24
+
25
+ export type MarketHeatmapUniverseId = "us-equity" | "us-etf";
26
+ type MarketHeatmapSource = "gloom";
27
+ type MarketHeatmapSizeKind = "market-cap" | "net-assets";
28
+ export interface MarketHeatmapAsset {
29
+ symbol: string;
30
+ name: string;
31
+ price: number;
32
+ change: number;
33
+ changePercent: number;
34
+ /**
35
+ * Whether the source actually carried a session change. `changePercent` keeps
36
+ * a numeric 0 for the shared screener row shape, so tiles must read this
37
+ * before showing a flat session that was really missing data.
38
+ */
39
+ hasChange: boolean;
40
+ size: number | null;
41
+ sizeKind: MarketHeatmapSizeKind;
42
+ volume: number | null;
43
+ currency: string;
44
+ exchange: string;
45
+ sector: string | null;
46
+ industry: string | null;
47
+ marketState: string | null;
48
+ source: MarketHeatmapSource;
49
+ }
50
+
51
+ export interface MarketHeatmapResult {
52
+ stale?: boolean;
53
+ universe: MarketHeatmapUniverseId;
54
+ source: MarketHeatmapSource;
55
+ fetchedAt: number;
56
+ assets: MarketHeatmapAsset[];
57
+ }
58
+
59
+
60
+ export interface MarketMoversPayload {
61
+ quotes: ScreenerQuote[];
62
+ source: "gloom";
63
+ stale: boolean;
64
+ asOf: string;
65
+ }
66
+
67
+ export interface DividendSummary {
68
+ trailingAnnualDividendRate: number | null;
69
+ trailingAnnualDividendYield: number | null;
70
+ forwardAnnualDividendRate: number | null;
71
+ payoutRatio: number | null;
72
+ exDividendDate: number | null;
73
+ dividendDate: number | null;
74
+ currency: string | null;
75
+ }
76
+
77
+ export interface MarketDividendsPayload {
78
+ stale?: boolean;
79
+ actions: CloudCorporateActionsPayload | null;
80
+ quote: CloudQuotePayload | null;
81
+ summary: DividendSummary | null;
82
+ historyError?: string;
83
+ summaryError?: string;
84
+ }
@@ -13,6 +13,8 @@ export type CloudHistoryParams = {
13
13
  endDate?: string;
14
14
  rangeKey?: string;
15
15
  historyRecovery?: HistoryRetention;
16
+ /** Ask for pre-market and after-hours bars too. */
17
+ session?: "extended";
16
18
  };
17
19
 
18
20
  export type CloudFredSeriesParams = {
@@ -172,6 +174,7 @@ export function cloudHistoryPath(
172
174
  if (params.endDate) search.set("endDate", params.endDate);
173
175
  if (params.rangeKey) search.set("rangeKey", params.rangeKey);
174
176
  if (params.historyRecovery) search.set("historyRecovery", JSON.stringify(params.historyRecovery));
177
+ if (params.session) search.set("session", params.session);
175
178
  return appendQuery("/market/history", search);
176
179
  }
177
180
 
@@ -311,30 +314,33 @@ export function cloudEarningsTranscriptPath(id: string): string {
311
314
  return `/cloud/transcripts/${encodeURIComponent(id)}`;
312
315
  }
313
316
 
314
- /** Executive compensation reads are open: no account, no plan. */
315
- export function publicProxyStatementsPath(ticker: string): string {
316
- return `/public/proxies/${encodeURIComponent(normalizeIssuerResearchTicker(ticker))}`;
317
+ /**
318
+ * RISK, EXEC and EK are Pro: these reads need a verified Pro account. The same
319
+ * risk factors and pay are open under /public for the gloom.sh pages.
320
+ */
321
+ export function cloudProxyStatementsPath(ticker: string): string {
322
+ return `/cloud/proxies/${encodeURIComponent(normalizeIssuerResearchTicker(ticker))}`;
317
323
  }
318
324
 
319
- export function publicFilingEventsPath(ticker: string, limit?: number): string {
325
+ export function cloudFilingEventsPath(ticker: string, limit?: number): string {
320
326
  const search = new URLSearchParams();
321
327
  if (limit != null) search.set("limit", String(limit));
322
328
  return appendQuery(
323
- `/public/events/${encodeURIComponent(normalizeIssuerResearchTicker(ticker))}`,
329
+ `/cloud/events/${encodeURIComponent(normalizeIssuerResearchTicker(ticker))}`,
324
330
  search,
325
331
  );
326
332
  }
327
333
 
328
- export function publicRiskReportsPath(ticker: string): string {
329
- return `/public/risks/${encodeURIComponent(normalizeIssuerResearchTicker(ticker))}`;
334
+ export function cloudRiskReportsPath(ticker: string): string {
335
+ return `/cloud/risks/${encodeURIComponent(normalizeIssuerResearchTicker(ticker))}`;
330
336
  }
331
337
 
332
- export function publicRiskReportPath(ticker: string, year: number): string {
333
- return `/public/risks/${encodeURIComponent(normalizeIssuerResearchTicker(ticker))}/${year}`;
338
+ export function cloudRiskReportPath(ticker: string, year: number): string {
339
+ return `/cloud/risks/${encodeURIComponent(normalizeIssuerResearchTicker(ticker))}/${year}`;
334
340
  }
335
341
 
336
- export function publicProxyStatementPath(ticker: string, year: number): string {
337
- return `/public/proxies/${encodeURIComponent(normalizeIssuerResearchTicker(ticker))}/${year}`;
342
+ export function cloudProxyStatementPath(ticker: string, year: number): string {
343
+ return `/cloud/proxies/${encodeURIComponent(normalizeIssuerResearchTicker(ticker))}/${year}`;
338
344
  }
339
345
 
340
346
  export function cloudSecFilingsPath(params: CloudSecFilingsParams): string {
@@ -17,6 +17,12 @@ import { SESSION_COOKIE_NAMES } from "./session-cookie";
17
17
 
18
18
  const DEFAULT_API_URL = "https://api.gloom.sh";
19
19
  const DEFAULT_MARKET_REQUEST_TIMEOUT_MS = 10_000;
20
+ const DEFAULT_RESEARCH_REQUEST_TIMEOUT_MS = 45_000;
21
+ // Research may fill missing sections after a primary read; quote/history reads remain latency bounded.
22
+ const RESEARCH_MARKET_PATHS = new Set([
23
+ "/market/dividends", "/market/short-interest", "/market/movers", "/market/trending",
24
+ "/market/heatmap", "/market/earnings-calendar",
25
+ ]);
20
26
  /** Local status for "this runtime cannot stream", never returned by the server. */
21
27
  export const STREAMING_UNSUPPORTED_STATUS = 0;
22
28
 
@@ -140,6 +146,7 @@ export class CloudApiRequestTransport {
140
146
  private cookieSessionMode = false;
141
147
  private readonly fetchTransport: CloudApiFetchTransport | null;
142
148
  private readonly marketRequestTimeoutMs: number;
149
+ private readonly researchRequestTimeoutMs: number;
143
150
  private readonly connectionHealth: ConnectionHealthRegistry;
144
151
 
145
152
  readonly baseUrl = getCloudApiBaseUrl();
@@ -154,6 +161,7 @@ export class CloudApiRequestTransport {
154
161
  this.fetchTransport = options.fetchTransport ?? null;
155
162
  this.marketRequestTimeoutMs =
156
163
  options.marketRequestTimeoutMs ?? DEFAULT_MARKET_REQUEST_TIMEOUT_MS;
164
+ this.researchRequestTimeoutMs = options.marketRequestTimeoutMs ?? DEFAULT_RESEARCH_REQUEST_TIMEOUT_MS;
157
165
  this.connectionHealth = options.connectionHealth ?? connectionHealth;
158
166
  }
159
167
 
@@ -257,6 +265,8 @@ export class CloudApiRequestTransport {
257
265
  return this.performRequest<T>(path, options, canApplySession);
258
266
  }
259
267
 
268
+ const timeoutMs = RESEARCH_MARKET_PATHS.has(path.split("?")[0]!)
269
+ ? this.researchRequestTimeoutMs : this.marketRequestTimeoutMs;
260
270
  const controller = new AbortController();
261
271
  const callerSignal = options?.signal;
262
272
  const abortFromCaller = () => controller.abort(callerSignal?.reason);
@@ -273,8 +283,8 @@ export class CloudApiRequestTransport {
273
283
  }, canApplySession);
274
284
  return await withDeadline(
275
285
  request,
276
- this.marketRequestTimeoutMs,
277
- `Cloud market request timed out after ${this.marketRequestTimeoutMs}ms: ${path}`,
286
+ timeoutMs,
287
+ `Cloud market request timed out after ${timeoutMs}ms: ${path}`,
278
288
  (error) => controller.abort(error),
279
289
  );
280
290
  } finally {
@@ -11,7 +11,7 @@ export interface TapeQuote {
11
11
  timestamp: string;
12
12
  bid: number | null;
13
13
  ask: number | null;
14
- /** Alpaca quote sizes are round lots. */
14
+ /** Quote sizes are round lots. */
15
15
  bidSize: number;
16
16
  askSize: number;
17
17
  bidExchange: string;
@@ -20,7 +20,7 @@ export interface TapeQuote {
20
20
  tape: string;
21
21
  }
22
22
  export interface TapeSnapshot {
23
- source: "Alpaca";
23
+ source: "Gloom Cloud";
24
24
  symbol: string;
25
25
  exchange: string;
26
26
  access: "realtime" | "delayed";
@@ -454,6 +454,7 @@ export interface CloudCdsHistoryResponse {
454
454
 
455
455
  interface CloudShortInterestPointPayload {
456
456
  settlementDate: string;
457
+ shortPercentFloat?: number | null;
457
458
  sharesShort: number;
458
459
  previousSharesShort: number | null;
459
460
  averageDailyVolume: number | null;
@@ -463,6 +464,7 @@ interface CloudShortInterestPointPayload {
463
464
  }
464
465
 
465
466
  export interface CloudShortInterestPayload {
467
+ source?: "finra" | "gloom";
466
468
  symbol: string;
467
469
  issueName: string | null;
468
470
  points: CloudShortInterestPointPayload[];
@@ -1291,6 +1293,8 @@ export interface CloudMarketResponse<T> {
1291
1293
  historyRetention?: unknown;
1292
1294
  /** Source-declared history semantics; validated separately from quote metadata. */
1293
1295
  historySession?: unknown;
1296
+ /** "extended" when the history includes the pre-market and after-hours bars asked for. */
1297
+ session?: unknown;
1294
1298
  /** Untrusted until the history adapter validates its boundary dates. */
1295
1299
  coverage?: CloudHistoryCoverage;
1296
1300
  providerMeta?: {
@@ -0,0 +1,33 @@
1
+ import { useCallback, useContext, type ReactNode } from "react";
2
+ import { RemoteUiRegistryProvider, useRemoteUiRegistry } from "../remote/semantic-tree";
3
+ import { AppContext, getEffectiveThemeId, useAppSelector } from "../state/app/context";
4
+ import { ThemeProvider } from "../theme/theme-context";
5
+ import { useRegisterDialogBridge } from "../ui/dialog-bridge";
6
+ import { KeybindingsProvider, useKeybindings } from "./keybindings";
7
+
8
+ function DialogTheme({ children }: { children: ReactNode }) {
9
+ const themeId = useAppSelector(getEffectiveThemeId);
10
+ return <ThemeProvider themeId={themeId}>{children}</ThemeProvider>;
11
+ }
12
+
13
+ /**
14
+ * Gives every dialog what the app gives its panes: the store, the theme, the
15
+ * keybindings and the remote registry, so a form in a dialog reads state and
16
+ * registers nodes like one in the app. Renders nothing.
17
+ */
18
+ export function AppDialogBridge() {
19
+ const store = useContext(AppContext);
20
+ const registry = useRemoteUiRegistry();
21
+ const keybindings = useKeybindings();
22
+ const bridge = useCallback((content: ReactNode) => {
23
+ const withKeybindings = <KeybindingsProvider value={keybindings}>{content}</KeybindingsProvider>;
24
+ const withRegistry = registry
25
+ ? <RemoteUiRegistryProvider registry={registry}>{withKeybindings}</RemoteUiRegistryProvider>
26
+ : withKeybindings;
27
+ return store
28
+ ? <AppContext value={store}><DialogTheme>{withRegistry}</DialogTheme></AppContext>
29
+ : withRegistry;
30
+ }, [keybindings, registry, store]);
31
+ useRegisterDialogBridge(bridge);
32
+ return null;
33
+ }
@@ -6,6 +6,7 @@ import {
6
6
  bringToFront,
7
7
  findDockLeaf,
8
8
  getDockedPaneIds,
9
+ isPaneDetached,
9
10
  isPaneInLayout,
10
11
  } from "../../layout/pane-manager";
11
12
  import type { PluginRegistry } from "../../plugins/registry";
@@ -52,6 +53,8 @@ interface AppPaneRuntimeArgs {
52
53
  dialog: DialogApi;
53
54
  dispatch: Dispatch<AppAction>;
54
55
  externalPlugins: readonly LoadedExternalPlugin[];
56
+ /** Desktop main window: raises a detached pane's own window. */
57
+ focusDetachedPane?: (paneId: string) => void;
55
58
  isDetachedWindow: boolean;
56
59
  notify: (body: string, options?: { type?: "info" | "success" | "error" }) => void;
57
60
  persistConfig: (nextConfig: AppState["config"]) => void;
@@ -67,6 +70,7 @@ export function useAppPaneRuntime({
67
70
  dialog,
68
71
  dispatch,
69
72
  externalPlugins,
73
+ focusDetachedPane,
70
74
  isDetachedWindow,
71
75
  notify,
72
76
  persistConfig,
@@ -159,7 +163,9 @@ export function useAppPaneRuntime({
159
163
  persistLayout(nextLayout, { pushHistory: false });
160
164
  }
161
165
  activatePane(paneId);
162
- }, [activatePane, persistLayout, state.config.layout]);
166
+ // Focus in this window's state alone would leave the pane's window behind this one.
167
+ if (isPaneDetached(nextLayout, paneId)) focusDetachedPane?.(paneId);
168
+ }, [activatePane, focusDetachedPane, persistLayout, state.config.layout]);
163
169
 
164
170
  const placePaneInstance = useCallback((
165
171
  instance: PaneInstanceConfig,
@@ -240,7 +246,6 @@ export function useAppPaneRuntime({
240
246
  const { createPaneFromTemplate } = useAppPaneTemplateRuntime({
241
247
  buildPaneInstance,
242
248
  dataProvider,
243
- dialog,
244
249
  dispatch,
245
250
  notify,
246
251
  placePaneInstance,
@@ -32,7 +32,7 @@ export function useAppPaneSettingsRuntime({
32
32
  stateRef,
33
33
  tickerRepository,
34
34
  }: UseAppPaneSettingsRuntimeOptions) {
35
- const openPaneSettings = useCallback(async (paneId?: string) => {
35
+ const openPaneSettings = useCallback(async (paneId?: string, options?: { fieldKey?: string }) => {
36
36
  const targetPaneId = paneId
37
37
  ? resolvePaneTarget(paneId)
38
38
  : stateRef.current.focusedPaneId;
@@ -59,6 +59,7 @@ export function useAppPaneSettingsRuntime({
59
59
  paneId={targetPaneId}
60
60
  pluginRegistry={pluginRegistry}
61
61
  applyFieldValue={applyFieldValue}
62
+ initialFieldKey={options?.fieldKey}
62
63
  />
63
64
  ),
64
65
  });