gloomberb 0.16.2 → 0.16.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (527) hide show
  1. package/package.json +4 -1
  2. package/src/api-client/askg.ts +43 -0
  3. package/src/api-client/auth.ts +15 -0
  4. package/src/api-client/beneficial-owners.ts +4 -0
  5. package/src/api-client/chat.ts +19 -0
  6. package/src/api-client/company-kpis.ts +14 -2
  7. package/src/api-client/data.ts +34 -16
  8. package/src/api-client/index.ts +12 -0
  9. package/src/api-client/normalizers.ts +27 -0
  10. package/src/api-client/paths.ts +88 -23
  11. package/src/api-client/request.ts +2 -1
  12. package/src/api-client/research-activity.ts +31 -0
  13. package/src/api-client/socket.ts +39 -8
  14. package/src/api-client/types.ts +57 -1
  15. package/src/api-client/upgrade-experiment.ts +90 -0
  16. package/src/app/global-shortcuts.ts +11 -1
  17. package/src/app/keybindings/actions.ts +10 -0
  18. package/src/app/pane-runtime/index.tsx +8 -0
  19. package/src/app/pane-runtime/pane-template-runtime.ts +5 -0
  20. package/src/app/pane-runtime/plugin-bindings.ts +65 -25
  21. package/src/app/pane-runtime/ticker-inspector-runtime.ts +12 -0
  22. package/src/app/pane-runtime/ticker-open-runtime.ts +18 -1
  23. package/src/app/runtime/desktop-deeplink.ts +5 -0
  24. package/src/app/star-prompt/model.ts +98 -0
  25. package/src/app/star-prompt/runtime.ts +41 -0
  26. package/src/app/star-prompt/status-line.tsx +190 -0
  27. package/src/app.tsx +13 -7
  28. package/src/architecture/core-builtin-allowlist.json +70 -0
  29. package/src/brokers/account-cache.ts +45 -0
  30. package/src/brokers/signed-in/adapter.ts +33 -2
  31. package/src/brokers/signed-in/client.ts +10 -0
  32. package/src/brokers/signed-in/sign-in-dialog.tsx +23 -9
  33. package/src/brokers/signed-in/sign-in.ts +62 -5
  34. package/src/capabilities/registry.ts +8 -1
  35. package/src/capabilities/types.ts +2 -0
  36. package/src/cli/command-options.ts +74 -0
  37. package/src/cli/commands/command-utils.ts +29 -0
  38. package/src/cli/commands/crypto-hints.ts +12 -4
  39. package/src/cli/commands/market.ts +524 -148
  40. package/src/cli/commands/options-chain.ts +172 -0
  41. package/src/cli/commands/options-leaps.ts +422 -0
  42. package/src/cli/commands/overview.ts +223 -42
  43. package/src/cli/commands/search.ts +29 -8
  44. package/src/cli/commands/system.ts +99 -19
  45. package/src/cli/commands/themes.ts +64 -0
  46. package/src/cli/commands/ticker.ts +200 -73
  47. package/src/cli/desktop-pane-shot.ts +100 -16
  48. package/src/cli/errors.ts +25 -2
  49. package/src/cli/freshness.ts +7 -4
  50. package/src/cli/fx-pair.ts +57 -0
  51. package/src/cli/help.ts +40 -7
  52. package/src/cli/history-rows.ts +187 -15
  53. package/src/cli/index-roots.ts +51 -0
  54. package/src/cli/index.ts +21 -13
  55. package/src/cli/listing-arg.ts +211 -3
  56. package/src/cli/not-a-ticker.ts +37 -0
  57. package/src/cli/options.ts +55 -7
  58. package/src/cli/pane-functions/capabilities.ts +13 -2
  59. package/src/cli/pane-functions/catalog.ts +13 -2
  60. package/src/cli/pane-functions/data.ts +36 -5
  61. package/src/cli/pane-functions/dom.ts +89 -28
  62. package/src/cli/pane-functions/freshness.ts +205 -26
  63. package/src/cli/pane-functions/function-help.ts +71 -24
  64. package/src/cli/pane-functions/headless.ts +168 -35
  65. package/src/cli/pane-functions/index.ts +12 -2
  66. package/src/cli/pane-functions/market-session.ts +133 -0
  67. package/src/cli/pane-functions/options.ts +15 -4
  68. package/src/cli/pane-functions/report-notices.ts +63 -0
  69. package/src/cli/pane-functions/report.ts +12 -1
  70. package/src/cli/pane-functions/resolver.ts +32 -8
  71. package/src/cli/pane-functions/screenshot-evidence.ts +2 -0
  72. package/src/cli/pane-functions/screenshot.ts +109 -23
  73. package/src/cli/registry.ts +8 -4
  74. package/src/cli/report-tables.ts +460 -0
  75. package/src/cli/result.ts +63 -16
  76. package/src/cli/row-window.ts +76 -0
  77. package/src/cli/scroll-truncation.ts +34 -0
  78. package/src/components/chart/composite/composite-chart.tsx +43 -4
  79. package/src/components/chart/composite/legend.tsx +39 -6
  80. package/src/components/chart/composite/rasterizer.ts +64 -4
  81. package/src/components/chart/composite/series-cues.ts +71 -0
  82. package/src/components/chart/composite/text-renderer.ts +16 -8
  83. package/src/components/chart/composite/types.ts +3 -0
  84. package/src/components/command-bar/commands/direct/index.ts +9 -1
  85. package/src/components/command-bar/commands/plugin/items.ts +3 -1
  86. package/src/components/command-bar/commands/registry.ts +7 -0
  87. package/src/components/command-bar/layout-items/focused-pane.ts +38 -0
  88. package/src/components/command-bar/pane-templates/workflow.ts +5 -0
  89. package/src/components/command-bar/routes/root/command-items.ts +2 -0
  90. package/src/components/command-bar/routes/root/plugin-turn-on.ts +92 -0
  91. package/src/components/command-bar/routes/root/results.ts +40 -10
  92. package/src/components/command-bar/routes/root/runtime.ts +8 -0
  93. package/src/components/command-bar/routes/root/search-providers.ts +97 -14
  94. package/src/components/command-bar/surface/index.tsx +18 -4
  95. package/src/components/command-bar/theme-picker.tsx +48 -13
  96. package/src/components/command-bar/workflow/ops.ts +5 -3
  97. package/src/components/data-table/export.ts +6 -51
  98. package/src/components/data-table/view.tsx +31 -10
  99. package/src/components/layout/floating-pane.tsx +6 -2
  100. package/src/components/layout/market-summary.ts +23 -9
  101. package/src/components/layout/pane/content.tsx +46 -29
  102. package/src/components/layout/pane/cycle-order.ts +2 -11
  103. package/src/components/layout/pane/header.tsx +2 -1
  104. package/src/components/layout/pane/title.ts +1 -1
  105. package/src/components/layout/presentation.ts +22 -0
  106. package/src/components/layout/shell/active-drag.ts +67 -35
  107. package/src/components/layout/shell/cursor-occlusion.ts +6 -5
  108. package/src/components/layout/shell/drag/index.ts +16 -7
  109. package/src/components/layout/shell/drag/live.ts +193 -0
  110. package/src/components/layout/shell/drag/overlays.tsx +179 -35
  111. package/src/components/layout/shell/drag/runtime.ts +62 -50
  112. package/src/components/layout/shell/drag/slide.ts +10 -0
  113. package/src/components/layout/shell/index.tsx +84 -57
  114. package/src/components/layout/shell/layout-state.ts +5 -11
  115. package/src/components/layout/shell/menu.ts +28 -1
  116. package/src/components/layout/shell/native/pointer-runtime.ts +13 -13
  117. package/src/components/layout/shell/native/surfaces.ts +30 -14
  118. package/src/components/layout/shell/pane/actions.ts +2 -1
  119. package/src/components/layout/shell/pane/layers.tsx +461 -180
  120. package/src/components/layout/shell/pane/management-shortcuts.ts +5 -0
  121. package/src/components/layout/shell/pane/new-layout.ts +116 -0
  122. package/src/components/layout/shell/shortcuts.ts +5 -2
  123. package/src/components/layout/shell/terminal-pointer-runtime.ts +18 -18
  124. package/src/components/layout/shell/visible-layout.ts +44 -1
  125. package/src/components/layout/shell/window-mode/overlays.tsx +12 -4
  126. package/src/components/layout/status-bar.tsx +4 -1
  127. package/src/components/markdown-text.tsx +9 -5
  128. package/src/components/metric-treemap/heat-surface.tsx +27 -8
  129. package/src/components/metric-treemap/heat-tiles.ts +48 -17
  130. package/src/components/onboarding/onboarding-frame.tsx +33 -10
  131. package/src/components/onboarding/onboarding-wizard.tsx +49 -40
  132. package/src/components/onboarding/portfolio-step/positions-panel.tsx +5 -2
  133. package/src/components/onboarding/pro-step-layout.ts +86 -0
  134. package/src/components/onboarding/use-onboarding-upgrade.ts +6 -2
  135. package/src/components/ui/button.tsx +10 -0
  136. package/src/components/ui/data-table/index.tsx +38 -0
  137. package/src/components/ui/data-table/types.ts +8 -1
  138. package/src/components/ui/data-table/visible-range.ts +2 -0
  139. package/src/components/ui/icon.tsx +11 -2
  140. package/src/components/ui/index.ts +1 -1
  141. package/src/core/connection-health.ts +1 -1
  142. package/src/core/state/app/layout-reducer.ts +89 -3
  143. package/src/core/state/app/state.ts +8 -5
  144. package/src/core/state/app/types.ts +13 -2
  145. package/src/data/config/layout.ts +55 -21
  146. package/src/data/config/store/fold-panes.ts +149 -0
  147. package/src/data/config/store/migrations.ts +7 -0
  148. package/src/data/config/store/node.ts +27 -6
  149. package/src/data/config/store/normalize.ts +37 -3
  150. package/src/data/json-persistence.ts +17 -3
  151. package/src/data/json-storage.ts +2 -0
  152. package/src/data/memory-resource-store.ts +46 -0
  153. package/src/i18n/es.ts +14 -1
  154. package/src/i18n/ja.ts +14 -1
  155. package/src/i18n/ko.ts +14 -1
  156. package/src/i18n/zh-cn.ts +14 -1
  157. package/src/i18n/zh-tw.ts +14 -1
  158. package/src/layout/desks.ts +1 -2
  159. package/src/layout/pane-layout-move.ts +264 -0
  160. package/src/layout/pane-manager/hidden-panes.ts +160 -0
  161. package/src/layout/pane-manager/index.ts +1 -0
  162. package/src/market-data/coordinator/entries.ts +7 -1
  163. package/src/market-data/coordinator/quotes.ts +2 -2
  164. package/src/market-data/market/freshness.ts +156 -11
  165. package/src/market-data/market/status.ts +40 -0
  166. package/src/market-data/options-alternatives.ts +69 -0
  167. package/src/market-data/quotes/contributions.ts +19 -2
  168. package/src/market-data/quotes/freshness.ts +5 -0
  169. package/src/market-data/quotes/metadata.ts +16 -0
  170. package/src/market-data/quotes/screener-live-quotes.ts +56 -5
  171. package/src/plugins/builtin/account-management/keyboard.ts +3 -0
  172. package/src/plugins/builtin/account-management/model.ts +1 -0
  173. package/src/plugins/builtin/account-management/navigation.ts +1 -1
  174. package/src/plugins/builtin/account-management/pane.tsx +31 -4
  175. package/src/plugins/builtin/alerts/quotes.ts +3 -0
  176. package/src/plugins/builtin/analytics/pane-model.ts +10 -6
  177. package/src/plugins/builtin/analytics/risk-headless.ts +3 -1
  178. package/src/plugins/builtin/analytics/risk-model.ts +37 -8
  179. package/src/plugins/builtin/analytics/risk-pane.tsx +8 -4
  180. package/src/plugins/builtin/attention/pane.tsx +1 -1
  181. package/src/plugins/builtin/backtest/pane.tsx +1 -1
  182. package/src/plugins/builtin/broker-manager/detail.tsx +4 -0
  183. package/src/plugins/builtin/broker-manager/index.tsx +7 -3
  184. package/src/plugins/builtin/broker-manager/model.ts +8 -0
  185. package/src/plugins/builtin/broker-manager/pane-actions.tsx +8 -2
  186. package/src/plugins/builtin/broker-manager/sign-in-end.ts +82 -0
  187. package/src/plugins/builtin/broker-manager/table.ts +5 -0
  188. package/src/plugins/builtin/builtin-plugin-meta.ts +121 -11
  189. package/src/plugins/builtin/catalysts/detail.tsx +1 -1
  190. package/src/plugins/builtin/chart-composer/pane.tsx +1 -1
  191. package/src/plugins/builtin/chat/channels.ts +34 -36
  192. package/src/plugins/builtin/chat/command-bar.ts +138 -0
  193. package/src/plugins/builtin/chat/composer-commands.ts +21 -1
  194. package/src/plugins/builtin/chat/content/composer-runtime.ts +11 -1
  195. package/src/plugins/builtin/chat/content/footer.tsx +5 -3
  196. package/src/plugins/builtin/chat/content/index.tsx +21 -1
  197. package/src/plugins/builtin/chat/content/mentions.ts +2 -1
  198. package/src/plugins/builtin/chat/content/user-map.ts +3 -1
  199. package/src/plugins/builtin/chat/controller/index.ts +48 -0
  200. package/src/plugins/builtin/chat/conversations.ts +256 -0
  201. package/src/plugins/builtin/chat/discord-command.ts +91 -0
  202. package/src/plugins/builtin/chat/edit-window.ts +12 -6
  203. package/src/plugins/builtin/chat/ghost-user.ts +14 -0
  204. package/src/plugins/builtin/chat/index.tsx +40 -2
  205. package/src/plugins/builtin/chat/layout.ts +2 -0
  206. package/src/plugins/builtin/chat/message/desktop.tsx +2 -1
  207. package/src/plugins/builtin/chat/message/header.tsx +24 -15
  208. package/src/plugins/builtin/chat/message/profile-popover.tsx +2 -1
  209. package/src/plugins/builtin/chat/message/render-state.ts +3 -0
  210. package/src/plugins/builtin/chat/pane-requests.ts +60 -0
  211. package/src/plugins/builtin/chat/pane-state.ts +32 -2
  212. package/src/plugins/builtin/chat/pane.tsx +8 -0
  213. package/src/plugins/builtin/cloud/askg/controller.ts +112 -4
  214. package/src/plugins/builtin/cloud/askg/conversation-store.ts +21 -0
  215. package/src/plugins/builtin/cloud/askg/manifest.ts +1 -0
  216. package/src/plugins/builtin/cloud/askg/model.ts +129 -70
  217. package/src/plugins/builtin/cloud/askg/pane.tsx +772 -377
  218. package/src/plugins/builtin/cloud/askg/protocol.ts +40 -2
  219. package/src/plugins/builtin/cloud/askg/tool-display.ts +437 -0
  220. package/src/plugins/builtin/cloud/askg/tool-timeline.tsx +403 -0
  221. package/src/plugins/builtin/cloud/company-picker.tsx +1 -9
  222. package/src/plugins/builtin/cloud/mcp-connect/command.ts +24 -0
  223. package/src/plugins/builtin/cloud/mcp-connect/dialog.tsx +360 -0
  224. package/src/plugins/builtin/cloud/mcp-connect/model.ts +135 -0
  225. package/src/plugins/builtin/cloud/mcp-connect/sections.ts +62 -0
  226. package/src/plugins/builtin/cloud/plugin.tsx +36 -1
  227. package/src/plugins/builtin/cloud/starter-symbols.ts +8 -0
  228. package/src/plugins/builtin/cloud/terminal-relay/acm-tab.tsx +89 -0
  229. package/src/plugins/builtin/cloud/terminal-relay/client.ts +97 -0
  230. package/src/plugins/builtin/cloud/terminal-relay/connect-section.tsx +57 -0
  231. package/src/plugins/builtin/cloud/terminal-relay/engine.ts +666 -0
  232. package/src/plugins/builtin/cloud/terminal-relay/grants.ts +137 -0
  233. package/src/plugins/builtin/cloud/terminal-relay/host.tsx +81 -0
  234. package/src/plugins/builtin/cloud/terminal-relay/indicator.tsx +82 -0
  235. package/src/plugins/builtin/cloud/terminal-relay/manifest.ts +234 -0
  236. package/src/plugins/builtin/cloud/terminal-relay/policy.ts +153 -0
  237. package/src/plugins/builtin/cloud/terminal-relay/prompts.tsx +168 -0
  238. package/src/plugins/builtin/cloud/terminal-relay/redact.ts +73 -0
  239. package/src/plugins/builtin/cloud/terminal-relay/summary.ts +62 -0
  240. package/src/plugins/builtin/cloud/upgrade-dialog.tsx +26 -2
  241. package/src/plugins/builtin/cloud/upgrade-personalization.ts +57 -0
  242. package/src/plugins/builtin/cloud/upgrade-tickers.ts +124 -0
  243. package/src/plugins/builtin/comment-letters/client.ts +1 -3
  244. package/src/plugins/builtin/company-attention/pane.tsx +1 -1
  245. package/src/plugins/builtin/company-kpis/client.ts +23 -8
  246. package/src/plugins/builtin/company-kpis/headless.ts +3 -1
  247. package/src/plugins/builtin/company-kpis/pane.tsx +15 -7
  248. package/src/plugins/builtin/company-kpis/screenshot-evidence.ts +10 -3
  249. package/src/plugins/builtin/composite-plugins.ts +107 -64
  250. package/src/plugins/builtin/credit-boards/cdx-pane.tsx +4 -4
  251. package/src/plugins/builtin/credit-boards/index.tsx +21 -21
  252. package/src/plugins/builtin/credit-boards/model.ts +0 -1
  253. package/src/plugins/builtin/credit-boards/pane.tsx +30 -0
  254. package/src/plugins/builtin/credit-boards/sovr-pane.tsx +4 -4
  255. package/src/plugins/builtin/debt-maturities/client.ts +37 -9
  256. package/src/plugins/builtin/debt-maturities/headless.ts +3 -1
  257. package/src/plugins/builtin/debt-maturities/pane.tsx +5 -4
  258. package/src/plugins/builtin/dividend-yield/index.tsx +1 -1
  259. package/src/plugins/builtin/dividend-yield/pane.tsx +1 -1
  260. package/src/plugins/builtin/earnings-calls/data.ts +28 -7
  261. package/src/plugins/builtin/earnings-calls/headless.ts +3 -2
  262. package/src/plugins/builtin/earnings-calls/pane.tsx +10 -5
  263. package/src/plugins/builtin/econ/calendar-model.ts +42 -17
  264. package/src/plugins/builtin/econ/detail-view.tsx +2 -2
  265. package/src/plugins/builtin/econ/index.tsx +68 -22
  266. package/src/plugins/builtin/econ-statistics/headless.ts +12 -2
  267. package/src/plugins/builtin/econ-statistics/pane.tsx +1 -1
  268. package/src/plugins/builtin/econ-statistics/view.ts +17 -0
  269. package/src/plugins/builtin/executives/data.ts +17 -6
  270. package/src/plugins/builtin/executives/pane.tsx +16 -7
  271. package/src/plugins/builtin/filing-events/pane.tsx +22 -5
  272. package/src/plugins/builtin/fx-matrix/freshness.ts +65 -0
  273. package/src/plugins/builtin/fx-matrix/index.tsx +22 -1
  274. package/src/plugins/builtin/fx-matrix/pairs.ts +1 -1
  275. package/src/plugins/builtin/fx-matrix/settings.ts +42 -2
  276. package/src/plugins/builtin/gpu/headless.ts +9 -3
  277. package/src/plugins/builtin/gpu/model.ts +14 -5
  278. package/src/plugins/builtin/help/index.tsx +1 -0
  279. package/src/plugins/builtin/holders/beneficial-client.ts +29 -7
  280. package/src/plugins/builtin/holders/beneficial-view.tsx +7 -3
  281. package/src/plugins/builtin/holders/client.ts +3 -6
  282. package/src/plugins/builtin/holders/format.ts +31 -1
  283. package/src/plugins/builtin/holders/headless.ts +32 -6
  284. package/src/plugins/builtin/holders/pane.tsx +25 -13
  285. package/src/plugins/builtin/holders/report-header.ts +46 -5
  286. package/src/plugins/builtin/insider/index.tsx +4 -4
  287. package/src/plugins/builtin/iv-history/charts.tsx +21 -7
  288. package/src/plugins/builtin/iv-history/client.ts +12 -2
  289. package/src/plugins/builtin/iv-history/format.ts +33 -2
  290. package/src/plugins/builtin/iv-history/headless.ts +22 -10
  291. package/src/plugins/builtin/iv-history/index.tsx +3 -3
  292. package/src/plugins/builtin/iv-history/model.ts +61 -13
  293. package/src/plugins/builtin/iv-history/pane.tsx +11 -3
  294. package/src/plugins/builtin/iv-history/screen-pane.tsx +42 -18
  295. package/src/plugins/builtin/jobs/pane.tsx +1 -1
  296. package/src/plugins/builtin/kelly-sizer/headless.ts +149 -0
  297. package/src/plugins/builtin/kelly-sizer/history.ts +80 -0
  298. package/src/plugins/builtin/kelly-sizer/index.tsx +2 -0
  299. package/src/plugins/builtin/kelly-sizer/pane.tsx +121 -45
  300. package/src/plugins/builtin/kelly-sizer/portfolio.ts +25 -0
  301. package/src/plugins/builtin/kelly-sizer/sections.tsx +14 -0
  302. package/src/plugins/builtin/kelly-sizer/types.ts +9 -1
  303. package/src/plugins/builtin/layout-manager/index.tsx +9 -1
  304. package/src/plugins/builtin/macro-day/client.ts +24 -0
  305. package/src/plugins/builtin/macro-day/headless.ts +11 -8
  306. package/src/plugins/builtin/macro-day/index.tsx +3 -0
  307. package/src/plugins/builtin/macro-day/model.ts +11 -6
  308. package/src/plugins/builtin/macro-day/pane.tsx +12 -8
  309. package/src/plugins/builtin/macro-day/release-table.ts +40 -0
  310. package/src/plugins/builtin/macro-day/releases.ts +62 -44
  311. package/src/plugins/builtin/market-heatmap/data.ts +25 -5
  312. package/src/plugins/builtin/market-heatmap/evidence.ts +90 -0
  313. package/src/plugins/builtin/market-heatmap/index.tsx +144 -63
  314. package/src/plugins/builtin/market-heatmap/model.ts +94 -3
  315. package/src/plugins/builtin/market-heatmap/portfolio.ts +12 -2
  316. package/src/plugins/builtin/market-movers/headless.ts +31 -4
  317. package/src/plugins/builtin/market-movers/index.tsx +8 -1
  318. package/src/plugins/builtin/market-movers/model.ts +71 -17
  319. package/src/plugins/builtin/market-movers/table.ts +50 -23
  320. package/src/plugins/builtin/members/pane.tsx +10 -0
  321. package/src/plugins/builtin/news/headless.ts +9 -2
  322. package/src/plugins/builtin/news/wire/news/footer.ts +10 -0
  323. package/src/plugins/builtin/openfda/client.ts +1 -1
  324. package/src/plugins/builtin/options/carry.ts +95 -0
  325. package/src/plugins/builtin/options/index.tsx +58 -5
  326. package/src/plugins/builtin/options/strike-window.ts +183 -0
  327. package/src/plugins/builtin/options/table.ts +55 -3
  328. package/src/plugins/builtin/options/types.ts +8 -1
  329. package/src/plugins/builtin/options/view.tsx +161 -12
  330. package/src/plugins/builtin/options-positioning/headless.ts +4 -2
  331. package/src/plugins/builtin/options-scenario/charts.tsx +2 -2
  332. package/src/plugins/builtin/options-scenario/client.ts +73 -17
  333. package/src/plugins/builtin/options-scenario/headless.ts +71 -24
  334. package/src/plugins/builtin/options-scenario/hedge.ts +284 -0
  335. package/src/plugins/builtin/options-scenario/index.tsx +9 -2
  336. package/src/plugins/builtin/options-scenario/model.ts +33 -0
  337. package/src/plugins/builtin/options-scenario/pane.tsx +40 -16
  338. package/src/plugins/builtin/pe-band/model.ts +2 -2
  339. package/src/plugins/builtin/pe-band/report-dates.ts +11 -7
  340. package/src/plugins/builtin/perps/equity-row.tsx +8 -5
  341. package/src/plugins/builtin/perps/model.ts +16 -5
  342. package/src/plugins/builtin/perps/pane.tsx +1 -1
  343. package/src/plugins/builtin/plugin-marketplace/model.ts +64 -21
  344. package/src/plugins/builtin/plugin-marketplace/packs.ts +118 -0
  345. package/src/plugins/builtin/plugin-marketplace/pane.tsx +344 -32
  346. package/src/plugins/builtin/plugin-marketplace/store.ts +7 -1
  347. package/src/plugins/builtin/plugin-module.ts +87 -4
  348. package/src/plugins/builtin/portfolio-list/account-metrics.ts +16 -1
  349. package/src/plugins/builtin/portfolio-list/allocation.ts +3 -0
  350. package/src/plugins/builtin/portfolio-list/cached-account.ts +18 -9
  351. package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +71 -36
  352. package/src/plugins/builtin/portfolio-list/cli/render.ts +89 -18
  353. package/src/plugins/builtin/portfolio-list/cli/shared.ts +2 -16
  354. package/src/plugins/builtin/portfolio-list/headless.ts +40 -7
  355. package/src/plugins/builtin/portfolio-list/pane/index.tsx +7 -4
  356. package/src/plugins/builtin/portfolio-list/summary/index.tsx +22 -4
  357. package/src/plugins/builtin/portfolio-list/summary/live-accounts.ts +11 -1
  358. package/src/plugins/builtin/realized-vol/headless.ts +3 -0
  359. package/src/plugins/builtin/realized-vol/pane.tsx +1 -1
  360. package/src/plugins/builtin/research/corporate-actions-pane.tsx +2 -2
  361. package/src/plugins/builtin/research/equity-diagnostic-pane.tsx +1 -1
  362. package/src/plugins/builtin/research/relative-valuation-model.ts +7 -3
  363. package/src/plugins/builtin/revenue-breakdown/client.ts +13 -6
  364. package/src/plugins/builtin/revenue-breakdown/headless.ts +4 -1
  365. package/src/plugins/builtin/revenue-breakdown/pane.tsx +7 -4
  366. package/src/plugins/builtin/reverse-dcf/headless.ts +5 -1
  367. package/src/plugins/builtin/reverse-dcf/model.ts +2 -1
  368. package/src/plugins/builtin/reverse-dcf/pane.tsx +1 -1
  369. package/src/plugins/builtin/risk-factors/data.ts +23 -9
  370. package/src/plugins/builtin/risk-factors/headless.ts +5 -2
  371. package/src/plugins/builtin/risk-factors/pane.tsx +6 -5
  372. package/src/plugins/builtin/seasonality/pane.tsx +1 -1
  373. package/src/plugins/builtin/sec/index.tsx +5 -5
  374. package/src/plugins/builtin/sectors/client.ts +10 -2
  375. package/src/plugins/builtin/sectors/headless.ts +35 -6
  376. package/src/plugins/builtin/sectors/index.tsx +18 -1
  377. package/src/plugins/builtin/sectors/sector-model.ts +150 -41
  378. package/src/plugins/builtin/shared/command-tab.ts +51 -0
  379. package/src/plugins/builtin/shared/headless-market-data.ts +33 -1
  380. package/src/plugins/builtin/shared/members-menu.tsx +260 -0
  381. package/src/plugins/builtin/shared/report-freshness.ts +50 -2
  382. package/src/plugins/builtin/shared/ticker-request.ts +25 -1
  383. package/src/plugins/builtin/shared/use-quote-board.ts +25 -5
  384. package/src/plugins/builtin/shared/volatility/options.ts +1 -46
  385. package/src/plugins/builtin/short-interest/index.tsx +19 -4
  386. package/src/plugins/builtin/short-interest/surface.tsx +4 -4
  387. package/src/plugins/builtin/short-volume/index.tsx +1 -10
  388. package/src/plugins/builtin/short-volume/pane.tsx +1 -1
  389. package/src/plugins/builtin/social-mentions/pane.tsx +1 -1
  390. package/src/plugins/builtin/supply-chain/model.ts +1 -1
  391. package/src/plugins/builtin/themes/pane.tsx +3 -0
  392. package/src/plugins/builtin/ticker-detail/financials/aggregation.ts +4 -0
  393. package/src/plugins/builtin/ticker-detail/financials/model.ts +25 -2
  394. package/src/plugins/builtin/ticker-detail/headless.ts +63 -25
  395. package/src/plugins/builtin/ticker-detail/overview/model.ts +9 -4
  396. package/src/plugins/builtin/ticker-detail/overview-tab.tsx +3 -2
  397. package/src/plugins/builtin/ticker-detail/pane.tsx +4 -5
  398. package/src/plugins/builtin/ticker-detail/quote-monitor/card.tsx +94 -6
  399. package/src/plugins/builtin/treasury-auctions/cache.ts +5 -2
  400. package/src/plugins/builtin/treasury-auctions/client.ts +22 -8
  401. package/src/plugins/builtin/treasury-auctions/headless.ts +40 -4
  402. package/src/plugins/builtin/treasury-auctions/index.tsx +11 -9
  403. package/src/plugins/builtin/treasury-auctions/model.ts +197 -30
  404. package/src/plugins/builtin/treasury-auctions/pane.tsx +35 -11
  405. package/src/plugins/builtin/treasury-auctions/types.ts +11 -1
  406. package/src/plugins/builtin/vol-surface/charts.tsx +1 -3
  407. package/src/plugins/builtin/vol-surface/client.ts +6 -2
  408. package/src/plugins/builtin/vol-surface/evidence.ts +11 -6
  409. package/src/plugins/builtin/vol-surface/headless.ts +124 -20
  410. package/src/plugins/builtin/vol-surface/model.ts +23 -11
  411. package/src/plugins/builtin/vol-surface/pane.tsx +38 -27
  412. package/src/plugins/builtin/vol-surface/tables.ts +124 -0
  413. package/src/plugins/builtin/world-indices/client.ts +22 -4
  414. package/src/plugins/builtin/world-indices/headless.ts +54 -27
  415. package/src/plugins/builtin/world-indices/model.ts +4 -2
  416. package/src/plugins/builtin/world-indices/table.tsx +13 -2
  417. package/src/plugins/builtin/world-venue-map/basemap-layer.tsx +2 -0
  418. package/src/plugins/builtin/world-venue-map/basemap.ts +18 -0
  419. package/src/plugins/builtin/world-venue-map/country-labels.ts +78 -0
  420. package/src/plugins/builtin/world-venue-map/geo-series.ts +1 -1
  421. package/src/plugins/builtin/world-venue-map/geo-svg.tsx +2 -1
  422. package/src/plugins/builtin/world-venue-map/index.ts +6 -6
  423. package/src/plugins/builtin/world-venue-map/layered-pane.tsx +27 -14
  424. package/src/plugins/builtin/world-venue-map/layers.ts +68 -10
  425. package/src/plugins/builtin/world-venue-map/map.tsx +198 -62
  426. package/src/plugins/builtin/world-venue-map/model.ts +16 -0
  427. package/src/plugins/builtin/world-venue-map/natural-earth/index.chunk.ts +3 -0
  428. package/src/plugins/builtin/world-venue-map/natural-earth/labels.chunk.ts +244 -0
  429. package/src/plugins/builtin/world-venue-map/pane.tsx +16 -10
  430. package/src/plugins/builtin/yield-curve/index.tsx +1 -1
  431. package/src/plugins/builtin-editorial.ts +126 -0
  432. package/src/plugins/catalog-backend.ts +16 -9
  433. package/src/plugins/catalog-browser.ts +127 -63
  434. package/src/plugins/catalog-manifest.ts +73 -40
  435. package/src/plugins/catalog-ui.ts +26 -6
  436. package/src/plugins/extracted-plugins.ts +7 -1
  437. package/src/plugins/ownership.ts +150 -7
  438. package/src/plugins/plugin-functions.ts +54 -0
  439. package/src/plugins/plugin-off.ts +36 -0
  440. package/src/plugins/registry/host-actions.ts +16 -0
  441. package/src/plugins/registry/index.ts +84 -24
  442. package/src/plugins/registry/plugin-state.ts +25 -1
  443. package/src/plugins/runtime/context.tsx +29 -0
  444. package/src/react/input.ts +48 -1
  445. package/src/remote/app-host.tsx +5 -0
  446. package/src/remote/controller.ts +3 -53
  447. package/src/remote/matching.ts +69 -0
  448. package/src/remote/schema.ts +1 -1
  449. package/src/remote/semantic-tree.tsx +14 -0
  450. package/src/remote/types.ts +2 -0
  451. package/src/renderers/browser/app-services.ts +3 -1
  452. package/src/renderers/dom/data-table/dom.ts +31 -0
  453. package/src/renderers/dom/data-table/index.tsx +5 -0
  454. package/src/renderers/dom/desktop/icons.tsx +14 -0
  455. package/src/renderers/dom/desktop/query-bar.tsx +59 -32
  456. package/src/renderers/dom/host/box.tsx +113 -17
  457. package/src/renderers/dom/host/drag-shield.ts +35 -0
  458. package/src/renderers/dom/host/live-frame.ts +62 -0
  459. package/src/renderers/dom/host/mouse.ts +8 -1
  460. package/src/renderers/dom/host/scroll-box.tsx +6 -5
  461. package/src/renderers/dom/host/tabs.tsx +3 -2
  462. package/src/renderers/dom/input-host.tsx +6 -1
  463. package/src/renderers/dom/styles.css +26 -5
  464. package/src/renderers/electrobun/bun/desktop/backend-requests.ts +7 -0
  465. package/src/renderers/electrobun/bun/desktop/backend.ts +7 -1
  466. package/src/renderers/electrobun/bun/desktop/detached-windows.ts +12 -1
  467. package/src/renderers/electrobun/bun/desktop/initialization.ts +15 -1
  468. package/src/renderers/electrobun/shared/protocol.ts +12 -1
  469. package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +4 -1
  470. package/src/renderers/electrobun/view/cli-pane-shot-frame.tsx +101 -5
  471. package/src/renderers/electrobun/view/host/native.ts +0 -10
  472. package/src/renderers/electrobun/view/host/window-move.ts +28 -0
  473. package/src/renderers/electrobun/view/main.tsx +4 -1
  474. package/src/renderers/electrobun/view/remote/persistence.ts +15 -2
  475. package/src/renderers/electrobun/view/ui-host.tsx +2 -5
  476. package/src/renderers/opentui/input-host.tsx +6 -1
  477. package/src/renderers/opentui/start.tsx +9 -0
  478. package/src/renderers/opentui/ui-host.tsx +7 -1
  479. package/src/shares/portable-layout.ts +16 -6
  480. package/src/sources/gloomberb-cloud/index.ts +19 -10
  481. package/src/sources/gloomberb-cloud/normalizers.ts +20 -21
  482. package/src/sources/listing-symbols.ts +11 -5
  483. package/src/sources/provider-errors.ts +88 -3
  484. package/src/sources/provider-router/batches.ts +3 -3
  485. package/src/sources/provider-router/cached-routes.ts +8 -4
  486. package/src/sources/provider-router/financial-routes.ts +13 -7
  487. package/src/sources/provider-router/financials.ts +106 -16
  488. package/src/sources/provider-router/history.ts +27 -11
  489. package/src/sources/provider-router/index.ts +1 -1
  490. package/src/sources/provider-router/primary.ts +24 -6
  491. package/src/sources/sec-edgar.ts +68 -8
  492. package/src/state/pane-scroll-registry.tsx +67 -35
  493. package/src/sync/core-contributors.ts +4 -3
  494. package/src/test-support/cli-context.ts +2 -1
  495. package/src/test-support/data-provider.ts +34 -0
  496. package/src/test-support/margin-account.ts +108 -0
  497. package/src/test-support/shell-pane-keys.tsx +1 -0
  498. package/src/theme/series-colors.ts +46 -0
  499. package/src/theme/themes.ts +149 -0
  500. package/src/tickers/search/index.ts +22 -2
  501. package/src/tickers/search/ranking.ts +45 -1
  502. package/src/tickers/search/types.ts +3 -1
  503. package/src/time-series/resolution.ts +15 -0
  504. package/src/time-series/resolve.ts +1 -14
  505. package/src/types/config.ts +61 -1
  506. package/src/types/financials.ts +32 -3
  507. package/src/types/headless.ts +11 -0
  508. package/src/types/instrument.ts +8 -0
  509. package/src/types/plugin.ts +49 -3
  510. package/src/ui/host.tsx +16 -0
  511. package/src/ui/index.tsx +10 -3
  512. package/src/ui/scroll-box-axis.ts +26 -0
  513. package/src/utils/cli-output.ts +14 -1
  514. package/src/utils/currency-units.ts +8 -3
  515. package/src/utils/depositary-receipt.ts +54 -10
  516. package/src/utils/display-number.ts +63 -0
  517. package/src/utils/exchanges.ts +13 -0
  518. package/src/utils/format.ts +2 -1
  519. package/src/utils/fundamentals.ts +17 -1
  520. package/src/utils/fx-market-hours.ts +34 -0
  521. package/src/utils/option-expiry.ts +126 -0
  522. package/src/utils/price-history-integrity.ts +19 -6
  523. package/src/utils/price-history.ts +39 -6
  524. package/src/utils/rpc-timeout-error.ts +6 -2
  525. package/src/utils/sec-eps-basis.ts +159 -30
  526. package/src/utils/sec.ts +38 -34
  527. package/src/utils/throttled-fetch.ts +51 -22
@@ -0,0 +1,10 @@
1
+ import type { CSSProperties } from "react";
2
+ import { WEB_CELL_HEIGHT, WEB_CELL_WIDTH } from "../../../../theme/font-scale";
3
+
4
+ /**
5
+ * Desktop: draws a box laid out at the shell's corner at cell (x, y) with a
6
+ * transform, so placing it somewhere else never lays anything out.
7
+ */
8
+ export function placeStyle(x: number, y: number): CSSProperties {
9
+ return { transform: `translate3d(${x * WEB_CELL_WIDTH}px, ${y * WEB_CELL_HEIGHT}px, 0)` };
10
+ }
@@ -41,11 +41,11 @@ import { tickerLinkMenuItems } from "./ticker-link-menu";
41
41
  import {
42
42
  makeSnapGuides,
43
43
  resolveExternalDockPreview,
44
- resolveHoverOverlay,
45
44
  } from "./drag";
46
45
  import { resolveAppHeaderHeightCells } from "./chrome";
46
+ import { useAppChromeShown } from "../presentation";
47
47
  import { useShellWindowMode } from "./window-mode";
48
- import { useShellNativeSurfaceWindowState } from "./native/surfaces";
48
+ import { ShellNativeSurfaceSync } from "./native/surfaces";
49
49
  import { ShellWindowModeOverlays } from "./window-mode/overlays";
50
50
  import { ShellPaneLayers } from "./pane/layers";
51
51
  import { paneMenuButtonAnchor, ShellActionMenuOverlay, type ActionMenuState } from "./action-menu-overlay";
@@ -59,14 +59,17 @@ import {
59
59
  useShellResolvedPanes,
60
60
  useShellVisibleLayout,
61
61
  } from "./layout-state";
62
+ import { restoreShellHiddenPanes } from "./visible-layout";
62
63
  import { AuthDialogHost } from "../../../plugins/builtin/cloud/auth-dialog";
63
64
  import { DeviceSignInDialogHost } from "../../../plugins/builtin/cloud/device-signin-dialog";
65
+ import { McpConnectDialogHost } from "../../../plugins/builtin/cloud/mcp-connect/dialog";
64
66
  import { BrokerSignInDialogHost } from "../../../brokers/signed-in/sign-in-dialog";
65
67
  import { FeedbackDialogHost } from "../../feedback-dialog";
66
68
  import { FormModalHost } from "../../form-modal";
67
69
  import type { AppTickerRepositoryPort } from "../../../core/app-service-ports";
68
70
  import type { DataProvider } from "../../../types/data-provider";
69
71
  import { useShellPaneActions } from "./pane/actions";
72
+ import { useShellPaneLayoutMoves } from "./pane/new-layout";
70
73
  import { resolvePaneFocusSourceLayout } from "./fullscreen";
71
74
  import { useTransientLayout } from "../transient-layout";
72
75
  import {
@@ -115,7 +118,6 @@ export function Shell({
115
118
  const commandBarOpen = useAppSelector((state) => state.commandBarOpen);
116
119
  const stateRef = useAppStateRef();
117
120
  const inputCaptured = useAppSelector((state) => state.inputCaptured);
118
- const statusBarVisible = useAppSelector((state) => state.statusBarVisible);
119
121
  const rendererHost = useRendererHost();
120
122
  const { setTransientLayout } = useTransientLayout();
121
123
  const uiKind = useUiHost().kind;
@@ -127,17 +129,14 @@ export function Shell({
127
129
  const { width, height } = useViewport();
128
130
  const shellRef = useRef<BoxRenderable | null>(null);
129
131
 
130
- const appHeaderHeight = resolveAppHeaderHeightCells({ titleBarOverlay, cellHeightPx });
131
- const contentHeight = Math.max(1, height - appHeaderHeight - (statusBarVisible ? 1 : 0));
132
+ const chrome = useAppChromeShown();
133
+ const appHeaderHeight = chrome.header ? resolveAppHeaderHeightCells({ titleBarOverlay, cellHeightPx }) : 0;
134
+ const contentHeight = Math.max(1, height - appHeaderHeight - (chrome.statusBar ? 1 : 0));
132
135
  pluginRegistry.bindHost({ getTermSize: () => ({ width, height: contentHeight }) });
133
136
 
134
137
  const layout = useAppSelector((state) => state.config.layout);
135
138
  const dialogOpen = useDialogState((dialog) => dialog.isOpen);
136
139
  const [hoveredPaneId, setHoveredPaneId] = useState<string | null>(null);
137
- const setHoveredPaneIfChanged = useCallback((paneId: string | null) => {
138
- if (commandBarOpen) return;
139
- setHoveredPaneId((current) => (current === paneId ? current : paneId));
140
- }, [commandBarOpen]);
141
140
  const [menuState, setMenuState] = useState<ActionMenuState | null>(null);
142
141
  const [transientFocusLayoutState, setTransientFocusLayoutState] = useState<TransientFocusLayoutState | null>(null);
143
142
  const transientFocusLayoutStateRef = useRef<TransientFocusLayoutState | null>(null);
@@ -165,21 +164,20 @@ export function Shell({
165
164
  if (commandBarOpen) setHoveredPaneId(null);
166
165
  }, [commandBarOpen]);
167
166
 
168
- const dragRuntime = useShellDragRuntimeState({
169
- contentHeight,
170
- throttleFloatingPreview: nativePaneChrome,
171
- width,
172
- });
167
+ const dragRuntime = useShellDragRuntimeState({ contentHeight, nativePaneChrome, width });
173
168
  const {
174
169
  cancelActiveDrag,
175
- dividerPreview,
176
- dockPreview,
177
- dragCursor,
178
- dragFloatingRect,
179
- dragRef,
180
170
  hasActiveDrag,
171
+ live,
181
172
  } = dragRuntime;
182
173
 
174
+ // A pane dragged across other headers is not hovering them: re-rendering
175
+ // the layout for their menu buttons would only cost frames.
176
+ const setHoveredPaneIfChanged = useCallback((paneId: string | null) => {
177
+ if (commandBarOpen || hasActiveDrag()) return;
178
+ setHoveredPaneId((current) => (current === paneId ? current : paneId));
179
+ }, [commandBarOpen, hasActiveDrag]);
180
+
183
181
  const { disabledPaneIds, visibleLayout } = useShellVisibleLayout({
184
182
  disabledPlugins: config.disabledPlugins,
185
183
  layout,
@@ -195,7 +193,15 @@ export function Shell({
195
193
  ), [nativePaneChrome, cellHeightPx]);
196
194
  const bounds = useMemo<LayoutBounds>(() => ({ x: 0, y: 0, width, height: contentHeight }), [contentHeight, width]);
197
195
 
198
- const persistLayout = useCallback((nextLayout: LayoutConfig, options?: { pushHistory?: boolean; focusedPaneId?: string | null }) => {
196
+ // Every edit here starts from the visible layout, so the panes it hides go
197
+ // back in before the layout is saved, rather than being deleted with it.
198
+ const persistLayout = useCallback((editedLayout: LayoutConfig, options?: { pushHistory?: boolean; focusedPaneId?: string | null }) => {
199
+ const nextLayout = restoreShellHiddenPanes(
200
+ stateRef.current.config.layout,
201
+ editedLayout,
202
+ disabledPaneIds,
203
+ pluginRegistry.panes,
204
+ );
199
205
  if (options?.pushHistory !== false) {
200
206
  dispatch({ type: "PUSH_LAYOUT_HISTORY" });
201
207
  }
@@ -209,7 +215,7 @@ export function Shell({
209
215
  currentState.paneState,
210
216
  hasFocusTarget ? (options.focusedPaneId ?? null) : currentState.focusedPaneId,
211
217
  ));
212
- }, [dispatch, stateRef]);
218
+ }, [disabledPaneIds, dispatch, pluginRegistry, stateRef]);
213
219
 
214
220
  const focusPane = useCallback((paneId: string) => {
215
221
  dispatch({ type: "FOCUS_PANE", paneId });
@@ -261,9 +267,10 @@ export function Shell({
261
267
  pluginRegistry,
262
268
  width,
263
269
  });
264
- const cursorOcclusionRects = useMemo(() => resolveShellCursorOcclusionRects({
270
+ // Read when the terminal draws a frame, so a pane on the move is covered where it is now.
271
+ const resolveCursorOcclusionRects = useCallback(() => resolveShellCursorOcclusionRects({
265
272
  contentHeight,
266
- dragFloatingRect,
273
+ dragFloatingRect: live.get().floating,
267
274
  nativePaneChrome,
268
275
  overlayOpen,
269
276
  transientFocusActive,
@@ -271,7 +278,7 @@ export function Shell({
271
278
  width,
272
279
  }), [
273
280
  contentHeight,
274
- dragFloatingRect,
281
+ live,
275
282
  nativePaneChrome,
276
283
  overlayOpen,
277
284
  transientFocusActive,
@@ -279,7 +286,7 @@ export function Shell({
279
286
  width,
280
287
  ]);
281
288
  useShellCursorOcclusionGuard({
282
- occlusionRects: cursorOcclusionRects,
289
+ resolveOcclusionRects: resolveCursorOcclusionRects,
283
290
  shellRef,
284
291
  });
285
292
 
@@ -378,6 +385,32 @@ export function Shell({
378
385
  [focusedPaneId, togglePaneFullscreen],
379
386
  );
380
387
  useEffect(() => pluginRegistry.bindHost({ togglePaneFullscreen }), [pluginRegistry, togglePaneFullscreen]);
388
+ // A pane leaving its layout leaves fullscreen with it, so the focus layout never points at it.
389
+ const leaveTransientFocusForPane = useCallback((paneId: string) => {
390
+ if (transientFocusLayoutStateRef.current?.paneId === paneId) setTransientFocusLayout(null);
391
+ }, [setTransientFocusLayout]);
392
+ const {
393
+ movePaneBack,
394
+ movePaneToNewLayout,
395
+ paneLayoutMoveMenu,
396
+ togglePaneNewLayout,
397
+ } = useShellPaneLayoutMoves({
398
+ closePaneMenu,
399
+ dispatch,
400
+ keybindings,
401
+ leavePane: leaveTransientFocusForPane,
402
+ pluginRegistry,
403
+ shortcutDisplayMode,
404
+ stateRef,
405
+ });
406
+ const toggleFocusedPaneNewLayout = useCallback(
407
+ () => togglePaneNewLayout(focusedPaneId),
408
+ [focusedPaneId, togglePaneNewLayout],
409
+ );
410
+ useEffect(
411
+ () => pluginRegistry.bindHost({ movePaneBack, movePaneToNewLayout }),
412
+ [movePaneBack, movePaneToNewLayout, pluginRegistry],
413
+ );
381
414
  const activateTransientFocusLayout = useCallback(() => {
382
415
  const current = transientFocusLayoutStateRef.current;
383
416
  if (!current) return;
@@ -460,29 +493,6 @@ export function Shell({
460
493
  () => resolveExternalDockPreview(desktopDockPreview, bounds),
461
494
  [bounds, desktopDockPreview],
462
495
  );
463
- const activePaneDrag = dragRef.current?.type === "pane-drag" ? dragRef.current : null;
464
- const activeHoverOverlay = activePaneDrag && dragCursor
465
- ? resolveHoverOverlay(dragCursor.x, dragCursor.y, dockLeafLayouts, activePaneDrag.paneId)
466
- : null;
467
- const effectiveDockPreview = dockPreview ?? externalDockPreview;
468
- useShellNativeSurfaceWindowState({
469
- activeHoverOverlay,
470
- activePaneDrag,
471
- appHeaderHeight,
472
- commandBarNativeOccluder,
473
- contentHeight,
474
- dialogOpen,
475
- dividerPreview,
476
- dockDividerLayouts: screenDividerLayouts,
477
- dockedPanes: screenDockedPanes,
478
- dragFloatingRect,
479
- effectiveDockPreview,
480
- menuState,
481
- nativeWindowModePanelRect,
482
- visibleFloatingPanes: screenFloatingPanes,
483
- width,
484
- windowModeDockMovePreview,
485
- });
486
496
 
487
497
  const titleState = useMemo(
488
498
  () => ({ config, paneState }) as Parameters<typeof resolveTickerForPane>[0],
@@ -579,6 +589,7 @@ export function Shell({
579
589
  startWindowMode,
580
590
  toggleFocusedPaneFullscreen,
581
591
  toggleFocusedPaneFloating,
592
+ toggleFocusedPaneNewLayout,
582
593
  });
583
594
 
584
595
  const openPaneMenu = useCallback((
@@ -645,6 +656,7 @@ export function Shell({
645
656
  toggle: () => { togglePaneFullscreen(paneId); },
646
657
  },
647
658
  paneFooterMenuItems(getPaneFooter(paneId)),
659
+ paneLayoutMoveMenu(paneId),
648
660
  );
649
661
  const showKitMenu = () => {
650
662
  const pluginItems = pluginRegistry.getContextMenuItems?.(context) ?? [];
@@ -686,7 +698,7 @@ export function Shell({
686
698
  void showContextMenu(context, items, event).then((shown) => {
687
699
  if (!shown) showKitMenu();
688
700
  });
689
- }, [canExportPaneCsv, closePaneMenu, contentHeight, copyPaneScreenshot, desktopWindowBridge, exportPaneCsv, focusPane, getPaneTitle, handlePaneQuickSetting, nativePaneChrome, togglePaneFullscreen, openPaneSettings, paneAccelerators, paneMap, paneState, persistLayout, pluginRegistry, publicSharing, rendererHost.copyPngImage, sharePane, shortcutDisplayMode, showContextMenu, titleState, visibleLayout, width]);
701
+ }, [canExportPaneCsv, closePaneMenu, contentHeight, copyPaneScreenshot, desktopWindowBridge, exportPaneCsv, focusPane, getPaneTitle, handlePaneQuickSetting, nativePaneChrome, togglePaneFullscreen, openPaneSettings, paneAccelerators, paneLayoutMoveMenu, paneMap, paneState, persistLayout, pluginRegistry, publicSharing, rendererHost.copyPngImage, sharePane, shortcutDisplayMode, showContextMenu, titleState, visibleLayout, width]);
690
702
  openPaneMenuRef.current = openPaneMenu;
691
703
 
692
704
  // The open pane menu owns the keyboard, ahead of any pane however late it
@@ -802,6 +814,7 @@ export function Shell({
802
814
  <DeviceSignInDialogHost />
803
815
  <BrokerSignInDialogHost />
804
816
  <AuthDialogHost />
817
+ <McpConnectDialogHost />
805
818
  <FeedbackDialogHost />
806
819
  {dataProvider && tickerRepository && (
807
820
  <FormModalHost dataProvider={dataProvider} pluginRegistry={pluginRegistry} tickerRepository={tickerRepository} />
@@ -824,12 +837,27 @@ export function Shell({
824
837
  </Box>
825
838
  </Box>
826
839
 
840
+ <ShellNativeSurfaceSync
841
+ appHeaderHeight={appHeaderHeight}
842
+ commandBarNativeOccluder={commandBarNativeOccluder}
843
+ contentHeight={contentHeight}
844
+ dialogOpen={dialogOpen}
845
+ dockDividerLayouts={screenDividerLayouts}
846
+ dockedPanes={screenDockedPanes}
847
+ dockLeafLayouts={dockLeafLayouts}
848
+ externalDockPreview={externalDockPreview}
849
+ live={live}
850
+ menuState={menuState}
851
+ nativeWindowModePanelRect={nativeWindowModePanelRect}
852
+ visibleFloatingPanes={screenFloatingPanes}
853
+ width={width}
854
+ windowModeDockMovePreview={windowModeDockMovePreview}
855
+ />
856
+
827
857
  <ShellPaneLayers
828
858
  contentHeight={contentHeight}
829
- dividerPreview={dividerPreview}
830
859
  dockDividerLayouts={dockDividerLayouts}
831
860
  dockLeafLayouts={dockLeafLayouts}
832
- dragFloatingRect={dragFloatingRect}
833
861
  focusedPaneId={focusedPaneId}
834
862
  getPaneTitle={getPaneTitle}
835
863
  getPaneQuickSettings={getPaneQuickSettings}
@@ -845,6 +873,7 @@ export function Shell({
845
873
  handleNativePaneMouseDown={handleNativePaneMouseDown}
846
874
  handlePaneAction={handlePaneAction}
847
875
  hoveredPaneId={hoveredPaneId}
876
+ live={live}
848
877
  menuPaneId={menuState?.paneId ?? null}
849
878
  nativeContextMenu={nativeContextMenu}
850
879
  nativePaneChrome={nativePaneChrome}
@@ -868,9 +897,9 @@ export function Shell({
868
897
  contentHeight={contentHeight}
869
898
  dockGeometryOptions={dockGeometryOptions}
870
899
  dockLeafLayouts={screenDockLeafLayouts}
871
- dragFloatingRect={dragFloatingRect}
872
900
  focusedPaneId={focusedPaneId}
873
901
  getPaneTitle={getPaneTitle}
902
+ live={live}
874
903
  menuOpen={!!menuState}
875
904
  nativePaneChrome={nativePaneChrome}
876
905
  nativeWindowModePanelRect={nativeWindowModePanelRect}
@@ -883,11 +912,9 @@ export function Shell({
883
912
  />
884
913
 
885
914
  <ShellDragOverlays
886
- activeHoverOverlay={activeHoverOverlay}
887
- activePaneDrag={activePaneDrag}
888
- dockPreview={dockPreview}
889
- dragFloatingRect={dragFloatingRect}
890
- effectiveDockPreview={effectiveDockPreview}
915
+ dockLeafLayouts={dockLeafLayouts}
916
+ externalDockPreview={externalDockPreview}
917
+ live={live}
891
918
  />
892
919
 
893
920
  <ShellActionMenuOverlay
@@ -8,7 +8,7 @@ import {
8
8
  import type { PluginRegistry } from "../../../plugins/registry";
9
9
  import type { LayoutConfig } from "../../../types/config";
10
10
  import { constrainFloatingRectToBounds } from "./drag";
11
- import { resolveShellVisibleLayout } from "./visible-layout";
11
+ import { collectDisabledPaneIds, resolveShellVisibleLayout } from "./visible-layout";
12
12
 
13
13
  interface ShellVisibleLayoutOptions {
14
14
  disabledPlugins: readonly string[];
@@ -24,16 +24,10 @@ export function useShellVisibleLayout({
24
24
  disabledPaneIds: Set<string>;
25
25
  visibleLayout: LayoutConfig;
26
26
  } {
27
- const disabledPaneIds = useMemo(() => {
28
- const pluginIds = new Set(disabledPlugins);
29
- const paneIds = new Set<string>();
30
- for (const pluginId of pluginIds) {
31
- for (const paneId of pluginRegistry.getPluginPaneIds(pluginId)) {
32
- paneIds.add(paneId);
33
- }
34
- }
35
- return paneIds;
36
- }, [disabledPlugins, pluginRegistry]);
27
+ const disabledPaneIds = useMemo(
28
+ () => collectDisabledPaneIds(pluginRegistry, disabledPlugins),
29
+ [disabledPlugins, pluginRegistry],
30
+ );
37
31
 
38
32
  const visibleLayout = useMemo(
39
33
  () => resolveShellVisibleLayout(layout, disabledPaneIds, pluginRegistry.panes),
@@ -15,7 +15,7 @@ import {
15
15
  type ShortcutDisplayMode,
16
16
  } from "../../../utils/shortcut-labels";
17
17
  import { PANE_MANAGEMENT_ACCELERATORS, type PaneManagementAccelerators } from "./shortcuts";
18
- import { t } from "../../../i18n";
18
+ import { t, tf } from "../../../i18n";
19
19
  import { displayWidth } from "../../../utils/format";
20
20
  import { fireAndForget } from "../../../utils/fire-and-forget";
21
21
 
@@ -42,6 +42,14 @@ export interface PaneMenuQuickSetting {
42
42
  toggle: () => void;
43
43
  }
44
44
 
45
+ /** Move to New Layout and Move Back as the pane menu offers them; either may be absent. */
46
+ export interface PaneMenuLayoutMove {
47
+ /** Absent when the pane is alone in its layout. */
48
+ moveToNewLayout?: () => void;
49
+ /** Present when the pane was moved here from another layout. */
50
+ moveBack?: { layoutName: string; onSelect: () => void };
51
+ }
52
+
45
53
  /**
46
54
  * The pane's own actions at the top of its menu: every footer hint with its
47
55
  * key, a footer shortcut such as `!`, then what the pane's kit controls add
@@ -93,6 +101,7 @@ export function menuForPane(
93
101
  quickSettings: PaneMenuQuickSetting[] = [],
94
102
  fullscreen?: { active: boolean; toggle: () => void },
95
103
  paneItems: ContextMenuItem[] = [],
104
+ layoutMove: PaneMenuLayoutMove = {},
96
105
  ): ContextMenuItem[] {
97
106
  const baseActions: ContextMenuItem[] = [...paneItems];
98
107
  if (baseActions.length > 0) baseActions.push(contextMenuDivider("pane:own-actions-divider"));
@@ -147,6 +156,24 @@ export function menuForPane(
147
156
  });
148
157
  }
149
158
 
159
+ if (layoutMove.moveToNewLayout) {
160
+ baseActions.push({
161
+ id: "move-to-new-layout",
162
+ label: "Move to New Layout",
163
+ accelerator: accelerators.newLayout,
164
+ onSelect: layoutMove.moveToNewLayout,
165
+ });
166
+ }
167
+ if (layoutMove.moveBack) {
168
+ baseActions.push({
169
+ id: "move-back",
170
+ label: tf("Move Back to {layout}", { layout: layoutMove.moveBack.layoutName }),
171
+ // The shortcut moves a pane back only when it is alone, where Move to New Layout is not offered.
172
+ accelerator: layoutMove.moveToNewLayout ? undefined : accelerators.newLayout,
173
+ onSelect: layoutMove.moveBack.onSelect,
174
+ });
175
+ }
176
+
150
177
  if (pane.floating) {
151
178
  baseActions.push({
152
179
  id: "dock",
@@ -42,7 +42,7 @@ export function useShellNativePointerRuntime({
42
42
  commandBarOpen = false,
43
43
  }: UseShellNativePointerRuntimeOptions) {
44
44
  const {
45
- dragRef,
45
+ startDrag,
46
46
  updateDividerPreview,
47
47
  updateDragFloatingRect,
48
48
  } = dragRuntime;
@@ -87,17 +87,17 @@ export function useShellNativePointerRuntime({
87
87
 
88
88
  const pointer = getShellPointer(event);
89
89
  focusNativePane(paneId);
90
- dragRef.current = {
90
+ startDrag({
91
91
  type: "pane-drag",
92
92
  paneId,
93
93
  mode: "floating",
94
94
  startX: pointer.x,
95
95
  startY: pointer.y,
96
96
  origRect: { x: rect.x, y: rect.y, width: rect.width, height: rect.height },
97
- };
97
+ });
98
98
  updateDragFloatingRect({ paneId, rect: { x: rect.x, y: rect.y, width: rect.width, height: rect.height } });
99
99
  event.preventDefault();
100
- }, [commandBarOpen, dragRef, focusNativePane, getShellPointer, nativePaneChrome, transientFocusActive, updateDragFloatingRect, windowMode]);
100
+ }, [commandBarOpen, focusNativePane, getShellPointer, nativePaneChrome, startDrag, transientFocusActive, updateDragFloatingRect, windowMode]);
101
101
 
102
102
  const startNativeDockedDrag = useCallback((paneId: string, rect: LayoutBounds, event: ShellMouseEvent) => {
103
103
  if (!nativePaneChrome) return;
@@ -108,16 +108,16 @@ export function useShellNativePointerRuntime({
108
108
 
109
109
  const pointer = getShellPointer(event);
110
110
  focusNativePane(paneId);
111
- dragRef.current = {
111
+ startDrag({
112
112
  type: "pane-drag",
113
113
  paneId,
114
114
  mode: "docked",
115
115
  startX: pointer.x,
116
116
  startY: pointer.y,
117
117
  origRect: { x: rect.x, y: rect.y, width: rect.width, height: rect.height },
118
- };
118
+ });
119
119
  event.preventDefault();
120
- }, [commandBarOpen, dragRef, focusNativePane, getShellPointer, nativePaneChrome, transientFocusActive, windowMode]);
120
+ }, [commandBarOpen, focusNativePane, getShellPointer, nativePaneChrome, startDrag, transientFocusActive, windowMode]);
121
121
 
122
122
  const startNativeFloatResize = useCallback((paneId: string, rect: FloatingRect, event: ShellMouseEvent) => {
123
123
  if (!nativePaneChrome) return;
@@ -130,17 +130,17 @@ export function useShellNativePointerRuntime({
130
130
  } else {
131
131
  focusNativePane(paneId);
132
132
  }
133
- dragRef.current = {
133
+ startDrag({
134
134
  type: "float-resize",
135
135
  paneId,
136
136
  startX: pointer.x,
137
137
  startY: pointer.y,
138
138
  origRect: { x: rect.x, y: rect.y, width: rect.width, height: rect.height },
139
- };
139
+ });
140
140
  updateDragFloatingRect({ paneId, rect: { x: rect.x, y: rect.y, width: rect.width, height: rect.height } });
141
141
  event.stopPropagation();
142
142
  event.preventDefault();
143
- }, [commandBarOpen, dragRef, focusNativePane, getShellPointer, nativePaneChrome, selectWindowModePane, transientFocusActive, updateDragFloatingRect, windowMode]);
143
+ }, [commandBarOpen, focusNativePane, getShellPointer, nativePaneChrome, selectWindowModePane, startDrag, transientFocusActive, updateDragFloatingRect, windowMode]);
144
144
 
145
145
  const startNativeDividerDrag = useCallback((divider: DockDividerLayout, event: ShellMouseEvent) => {
146
146
  if (!nativePaneChrome) return;
@@ -152,7 +152,7 @@ export function useShellNativePointerRuntime({
152
152
  setMenuState(null);
153
153
  setHoveredMenuItemId(null);
154
154
  }
155
- dragRef.current = {
155
+ startDrag({
156
156
  type: "divider",
157
157
  path: divider.path,
158
158
  axis: divider.axis,
@@ -160,7 +160,7 @@ export function useShellNativePointerRuntime({
160
160
  startY: pointer.y,
161
161
  startRatio: divider.ratio,
162
162
  bounds: divider.bounds,
163
- };
163
+ });
164
164
  updateDividerPreview({
165
165
  pathKey: divider.path.join("."),
166
166
  rect: divider.rect,
@@ -168,7 +168,7 @@ export function useShellNativePointerRuntime({
168
168
  });
169
169
  event.stopPropagation();
170
170
  event.preventDefault();
171
- }, [commandBarOpen, dragRef, getShellPointer, menuState, nativePaneChrome, setHoveredMenuItemId, setMenuState, transientFocusActive, updateDividerPreview]);
171
+ }, [commandBarOpen, getShellPointer, menuState, nativePaneChrome, setHoveredMenuItemId, setMenuState, startDrag, transientFocusActive, updateDividerPreview]);
172
172
 
173
173
  const handlePaneAction = useCallback((paneId: string, rect: LayoutBounds, event: ShellMouseEvent) => {
174
174
  if (commandBarOpen) return;
@@ -1,17 +1,18 @@
1
1
  import { useEffect, useMemo } from "react";
2
2
  import type {
3
3
  DockDividerLayout,
4
+ DockLeafLayout,
4
5
  FloatingRect,
5
6
  LayoutBounds,
6
7
  ResolvedPane,
7
8
  } from "../../../../layout/pane-manager";
8
9
  import { useNativeRenderer } from "../../../../ui";
9
10
  import type { DragPreview } from "../drag";
11
+ import { IDLE_DRAG, useLiveDrag, useLiveHoverOverlay, type LiveDragGeometry, type LiveDragStore } from "../drag/live";
10
12
  import {
11
13
  buildNativeTransientOccluders,
12
14
  buildNativeWindowState,
13
15
  resolveNativeDockDividers,
14
- type DividerPreviewState,
15
16
  } from "./window-state";
16
17
  import type { WindowEditDockMovePreview } from "../../window-edit/presentation";
17
18
 
@@ -24,18 +25,18 @@ interface ShellNativeSurfaceMenuState {
24
25
  maxRows?: number;
25
26
  }
26
27
 
27
- interface UseShellNativeSurfaceWindowStateOptions {
28
- activeHoverOverlay: Parameters<typeof buildNativeTransientOccluders>[0]["activeHoverOverlay"];
29
- activePaneDrag: { paneId: string; mode: "docked" | "floating" } | null;
28
+ interface ShellNativeSurfaceSyncProps {
30
29
  appHeaderHeight: number;
31
30
  commandBarNativeOccluder: LayoutBounds | null;
32
31
  contentHeight: number;
33
32
  dialogOpen: boolean;
34
- dividerPreview: DividerPreviewState | null;
35
33
  dockDividerLayouts: DockDividerLayout[];
36
34
  dockedPanes: ResolvedPane[];
37
- dragFloatingRect: { paneId: string; rect: FloatingRect } | null;
38
- effectiveDockPreview: DragPreview | null;
35
+ /** The tiled panes a moving pane can be dropped on. */
36
+ dockLeafLayouts: DockLeafLayout[];
37
+ /** A pane from another window over this one's edge. */
38
+ externalDockPreview: DragPreview | null;
39
+ live: LiveDragStore;
39
40
  menuState: ShellNativeSurfaceMenuState | null;
40
41
  nativeWindowModePanelRect: LayoutBounds | null;
41
42
  visibleFloatingPanes: Array<{ pane: ResolvedPane; rect: FloatingRect }>;
@@ -43,26 +44,40 @@ interface UseShellNativeSurfaceWindowStateOptions {
43
44
  windowModeDockMovePreview: WindowEditDockMovePreview | null;
44
45
  }
45
46
 
46
- export function useShellNativeSurfaceWindowState({
47
- activeHoverOverlay,
48
- activePaneDrag,
47
+ const NO_LEAVES: DockLeafLayout[] = [];
48
+ const selectAll = (geometry: LiveDragGeometry) => geometry;
49
+ const selectIdle = () => IDLE_DRAG;
50
+
51
+ /**
52
+ * Keeps the native image surfaces clear of the layout. A component of its own,
53
+ * so following a drag redraws nothing but this.
54
+ */
55
+ export function ShellNativeSurfaceSync({
49
56
  appHeaderHeight,
50
57
  commandBarNativeOccluder,
51
58
  contentHeight,
52
59
  dialogOpen,
53
- dividerPreview,
54
60
  dockDividerLayouts,
55
61
  dockedPanes,
56
- dragFloatingRect,
57
- effectiveDockPreview,
62
+ dockLeafLayouts,
63
+ externalDockPreview,
64
+ live,
58
65
  menuState,
59
66
  nativeWindowModePanelRect,
60
67
  visibleFloatingPanes,
61
68
  width,
62
69
  windowModeDockMovePreview,
63
- }: UseShellNativeSurfaceWindowStateOptions) {
70
+ }: ShellNativeSurfaceSyncProps): null {
64
71
  // Only terminal hosts draw kitty images that need to stay clear of the layout.
65
72
  const nativeSurfaceManager = useNativeRenderer().nativeSurfaceManager;
73
+ const {
74
+ paneDrag: activePaneDrag,
75
+ floating: dragFloatingRect,
76
+ divider: dividerPreview,
77
+ dockPreview,
78
+ } = useLiveDrag(live, nativeSurfaceManager ? selectAll : selectIdle);
79
+ const effectiveDockPreview = dockPreview ?? externalDockPreview;
80
+ const activeHoverOverlay = useLiveHoverOverlay(live, nativeSurfaceManager ? dockLeafLayouts : NO_LEAVES);
66
81
  const nativeTransientOccluders = useMemo(() => buildNativeTransientOccluders({
67
82
  activeHoverOverlay,
68
83
  activePaneDrag,
@@ -124,4 +139,5 @@ export function useShellNativeSurfaceWindowState({
124
139
  useEffect(() => {
125
140
  nativeSurfaceManager?.setWindowState(nativeWindowState);
126
141
  }, [nativeSurfaceManager, nativeWindowState]);
142
+ return null;
127
143
  }
@@ -172,7 +172,8 @@ export function useShellPaneActions({
172
172
  paneTypes: pluginRegistry.panes,
173
173
  apply: persistLayout,
174
174
  notify: pluginRegistry.notify,
175
- onRevert: () => pluginRegistry.updateLayout(visibleLayout),
175
+ // Back through the shell's save, which puts hidden panes back too.
176
+ onRevert: () => persistLayout(visibleLayout),
176
177
  });
177
178
  return true;
178
179
  }, [contentHeight, persistLayout, pluginRegistry, visibleLayout, width]);