gloomberb 0.13.2 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1402) hide show
  1. package/README.md +37 -302
  2. package/README.zh-CN.md +47 -239
  3. package/package.json +16 -8
  4. package/src/api-client/askg.test.ts +256 -0
  5. package/src/api-client/askg.ts +544 -0
  6. package/src/api-client/auth.ts +110 -50
  7. package/src/api-client/chat.ts +58 -24
  8. package/src/api-client/collections.ts +53 -0
  9. package/src/api-client/data.ts +260 -69
  10. package/src/api-client/errors.ts +31 -4
  11. package/src/api-client/index.test.ts +568 -303
  12. package/src/api-client/index.ts +374 -476
  13. package/src/api-client/normalizers.ts +43 -13
  14. package/src/api-client/notes.ts +89 -0
  15. package/src/api-client/paths.test.ts +32 -0
  16. package/src/api-client/paths.ts +169 -36
  17. package/src/api-client/request.test.ts +35 -18
  18. package/src/api-client/request.ts +170 -34
  19. package/src/api-client/research-activity.test.ts +316 -0
  20. package/src/api-client/research-activity.ts +339 -32
  21. package/src/api-client/session-request-lifetime.test.ts +184 -0
  22. package/src/api-client/socket-health.test.ts +18 -12
  23. package/src/api-client/socket-lifetime.test.ts +76 -0
  24. package/src/api-client/socket.ts +279 -75
  25. package/src/api-client/teams.test.ts +270 -0
  26. package/src/api-client/teams.ts +241 -0
  27. package/src/api-client/theses.ts +177 -0
  28. package/src/api-client/types.ts +757 -10
  29. package/src/api-client/views.ts +125 -0
  30. package/src/app/global-shortcuts.test.tsx +5 -37
  31. package/src/app/pane-runtime/plugin-bindings.ts +125 -6
  32. package/src/app/pane-runtime/ticker-navigation-runtime.test.ts +144 -0
  33. package/src/app/pane-runtime/ticker-open-runtime.test.tsx +170 -0
  34. package/src/app/pane-runtime/ticker-open-runtime.ts +68 -12
  35. package/src/app/runtime/desktop-deeplink.test.ts +44 -1
  36. package/src/app/runtime/desktop-deeplink.ts +22 -11
  37. package/src/app/runtime/layout-warmup.test.ts +73 -0
  38. package/src/app/runtime/layout-warmup.ts +118 -0
  39. package/src/app/runtime/startup.ts +47 -2
  40. package/src/app/runtime/ticker-refresh.test.tsx +115 -0
  41. package/src/app/runtime/ticker-refresh.ts +109 -157
  42. package/src/app.tsx +32 -6
  43. package/src/architecture/browser-entry-graph.test.ts +1 -0
  44. package/src/architecture/import-boundaries.test.ts +14 -0
  45. package/src/brokers/bond-price-basis.test.ts +35 -0
  46. package/src/brokers/broker-ticker-sync.ts +6 -2
  47. package/src/brokers/legacy-contract.test.ts +51 -0
  48. package/src/brokers/sync-broker-instance.test.ts +70 -0
  49. package/src/capabilities/factories.ts +4 -0
  50. package/src/capabilities/index.ts +1 -0
  51. package/src/capabilities/service-capabilities.ts +43 -3
  52. package/src/capabilities/stream-client.ts +39 -0
  53. package/src/cli/base-converter.test.ts +16 -0
  54. package/src/cli/base-converter.ts +5 -4
  55. package/src/cli/commands/automation.ts +1 -147
  56. package/src/cli/commands/futures-price-precision.test.tsx +65 -0
  57. package/src/cli/commands/market-fx.test.ts +59 -0
  58. package/src/cli/commands/market.ts +10 -5
  59. package/src/cli/commands/overview.ts +1 -32
  60. package/src/cli/commands/plugins.ts +461 -79
  61. package/src/cli/commands/quote-price-basis.test.ts +82 -0
  62. package/src/cli/commands/system.ts +83 -5
  63. package/src/cli/commands/ticker-financial-units.test.ts +43 -0
  64. package/src/cli/commands/ticker-period.test.ts +62 -0
  65. package/src/cli/commands/ticker.ts +170 -106
  66. package/src/cli/desktop-pane-shot.ts +98 -7
  67. package/src/cli/entry.test.ts +55 -0
  68. package/src/cli/entry.ts +13 -6
  69. package/src/cli/helpers.ts +5 -3
  70. package/src/cli/index.ts +6 -3
  71. package/src/cli/native-smoke.ts +16 -0
  72. package/src/cli/pane-functions/capabilities.ts +9 -383
  73. package/src/cli/pane-functions/catalog.ts +6 -5
  74. package/src/cli/pane-functions/cloud-session.test.ts +23 -0
  75. package/src/cli/pane-functions/cloud-session.ts +9 -0
  76. package/src/cli/pane-functions/data.ts +0 -6
  77. package/src/cli/pane-functions/discovery.test.ts +36 -0
  78. package/src/cli/pane-functions/discovery.ts +30 -18
  79. package/src/cli/pane-functions/headless.test.ts +67 -0
  80. package/src/cli/pane-functions/headless.ts +24 -6
  81. package/src/cli/pane-functions/index.test.ts +29 -0
  82. package/src/cli/pane-functions/index.ts +1 -1
  83. package/src/cli/pane-functions/intraday-shot.test.ts +84 -20
  84. package/src/cli/pane-functions/options.ts +5 -2
  85. package/src/cli/pane-functions/report.test.ts +6 -3
  86. package/src/cli/pane-functions/report.ts +5 -857
  87. package/src/cli/pane-functions/resolver.ts +1 -1
  88. package/src/cli/pane-functions/screenshot.test.ts +27 -6
  89. package/src/cli/pane-functions/screenshot.ts +179 -135
  90. package/src/cli/registry.test.ts +24 -50
  91. package/src/cli/result.test.ts +18 -0
  92. package/src/cli/result.ts +3 -1
  93. package/src/cli.test.ts +14 -5
  94. package/src/components/chart/composite/axis-overlays.tsx +4 -2
  95. package/src/components/chart/composite/column-layout.ts +2 -2
  96. package/src/components/chart/composite/composite-chart.test.tsx +164 -7
  97. package/src/components/chart/composite/composite-chart.tsx +131 -30
  98. package/src/components/chart/composite/format.test.ts +74 -0
  99. package/src/components/chart/composite/format.ts +85 -12
  100. package/src/components/chart/composite/fx-precision.test.ts +92 -0
  101. package/src/components/chart/composite/interactions.test.ts +13 -0
  102. package/src/components/chart/composite/interactions.ts +3 -1
  103. package/src/components/chart/composite/panel-series.ts +2 -0
  104. package/src/components/chart/composite/price-axis-labels.test.ts +8 -0
  105. package/src/components/chart/composite/price-axis-labels.tsx +3 -1
  106. package/src/components/chart/composite/price-series.ts +18 -11
  107. package/src/components/chart/composite/renderers.test.ts +5 -5
  108. package/src/components/chart/composite/scene-market-cursor.test.ts +148 -0
  109. package/src/components/chart/composite/scene.test.ts +166 -0
  110. package/src/components/chart/composite/scene.ts +57 -21
  111. package/src/{plugins/prediction-markets/chart.test.tsx → components/chart/composite/scroll-surface.test.tsx} +34 -22
  112. package/src/components/chart/composite/text-renderer.ts +5 -2
  113. package/src/components/chart/composite/time-axis.test.ts +11 -2
  114. package/src/components/chart/composite/time-axis.ts +8 -5
  115. package/src/components/chart/composite/types.ts +9 -0
  116. package/src/components/chart/native/kitty/index.test.ts +4 -79
  117. package/src/components/chart/static/chart-surface.test.tsx +13 -0
  118. package/src/components/chart/static/chart-surface.tsx +19 -11
  119. package/src/components/chart/static/series.ts +3 -3
  120. package/src/components/command-bar/assist/model.test.ts +66 -0
  121. package/src/components/command-bar/assist/model.ts +82 -7
  122. package/src/components/command-bar/commands/collection.ts +27 -7
  123. package/src/components/command-bar/commands/direct/runtime.ts +7 -2
  124. package/src/components/command-bar/list/model.ts +9 -0
  125. package/src/components/command-bar/list/view.tsx +25 -83
  126. package/src/components/command-bar/multi-select-picker.tsx +6 -8
  127. package/src/components/command-bar/pane-actions.ts +13 -7
  128. package/src/components/command-bar/pane-templates/workflow.ts +28 -3
  129. package/src/components/command-bar/panel/index.tsx +189 -76
  130. package/src/components/command-bar/panel/layout.test.ts +32 -0
  131. package/src/components/command-bar/panel/layout.ts +9 -1
  132. package/src/components/command-bar/panel/palette.ts +28 -0
  133. package/src/components/command-bar/panel/state.ts +6 -0
  134. package/src/components/command-bar/panel/types.ts +1 -14
  135. package/src/components/command-bar/routes/ticker-search/actions.ts +33 -12
  136. package/src/components/command-bar/routes/ticker-search/results.test.ts +42 -1
  137. package/src/components/command-bar/routes/ticker-search/results.ts +14 -11
  138. package/src/components/command-bar/routing/actions.ts +9 -8
  139. package/src/components/command-bar/surface/index.tsx +20 -1
  140. package/src/components/command-bar/surface/listing-selection.test.tsx +84 -0
  141. package/src/components/command-bar/surface/test-harness.tsx +11 -93
  142. package/src/components/command-bar/theme-picker.tsx +12 -27
  143. package/src/components/command-bar/workflow/body.tsx +8 -35
  144. package/src/components/command-bar/workflow/builtin.ts +55 -14
  145. package/src/components/command-bar/workflow/collection-actions.test.ts +11 -0
  146. package/src/components/command-bar/workflow/collection-actions.ts +50 -11
  147. package/src/components/command-bar/workflow/collection-identity.test.ts +180 -0
  148. package/src/components/command-bar/workflow/collection-ticker.ts +65 -0
  149. package/src/components/command-bar/workflow/coordinator.ts +0 -1
  150. package/src/components/command-bar/workflow/field-row.tsx +20 -35
  151. package/src/components/command-bar/workflow/ops.test.ts +167 -1
  152. package/src/components/command-bar/workflow/ops.ts +59 -3
  153. package/src/components/command-bar/workflow/runtime.ts +13 -0
  154. package/src/components/command-bar/workflow/submit.ts +9 -2
  155. package/src/components/command-bar/workflow/ticker-listing-picker.test.ts +41 -0
  156. package/src/components/command-bar/workflow/ticker-listing-picker.ts +35 -0
  157. package/src/components/command-bar/workflow/tickers.ts +42 -11
  158. package/src/components/data-table/export.ts +4 -1
  159. package/src/components/data-table/frozen-column.test.tsx +114 -0
  160. package/src/components/data-table/horizontal-navigation.test.tsx +154 -0
  161. package/src/components/data-table/stack-view.test.tsx +23 -18
  162. package/src/components/data-table/stack-view.tsx +37 -1
  163. package/src/components/data-table/view.test.tsx +107 -63
  164. package/src/components/data-table/view.tsx +40 -3
  165. package/src/components/feed-data-table/stack-view.tsx +20 -5
  166. package/src/components/index.ts +40 -15
  167. package/src/components/layout/detached-pane-shell.tsx +71 -17
  168. package/src/components/layout/floating-pane.tsx +7 -0
  169. package/src/components/layout/header.tsx +3 -0
  170. package/src/components/layout/market-summary.ts +1 -1
  171. package/src/components/layout/missing-pane.tsx +111 -0
  172. package/src/components/layout/pane/content.tsx +29 -9
  173. package/src/components/layout/pane/footer/current-actions.test.tsx +108 -0
  174. package/src/components/layout/pane/footer/index.tsx +44 -3
  175. package/src/components/layout/pane/footer/model.ts +11 -0
  176. package/src/components/layout/pane/footer/notice.desktop.test.tsx +56 -0
  177. package/src/components/layout/pane/footer/registration.tsx +32 -1
  178. package/src/components/layout/pane/header.tsx +31 -1
  179. package/src/components/layout/pane/index.tsx +3 -0
  180. package/src/components/layout/pane/sizing.test.ts +1 -0
  181. package/src/components/layout/pane/sizing.ts +4 -1
  182. package/src/components/layout/shell/chrome.ts +7 -2
  183. package/src/components/layout/shell/index.test.tsx +117 -34
  184. package/src/components/layout/shell/index.tsx +42 -22
  185. package/src/components/layout/shell/menu.test.ts +34 -0
  186. package/src/components/layout/shell/menu.ts +9 -0
  187. package/src/components/layout/shell/pane/actions.ts +20 -3
  188. package/src/components/layout/shell/pane/layers.tsx +26 -0
  189. package/src/components/layout/shell/pane-occlusion.test.ts +52 -0
  190. package/src/components/layout/shell/pane-occlusion.ts +63 -0
  191. package/src/components/layout/status-bar-groups.test.ts +92 -0
  192. package/src/components/layout/status-bar-groups.ts +85 -0
  193. package/src/components/layout/status-bar.test.tsx +6 -6
  194. package/src/components/layout/status-bar.tsx +140 -31
  195. package/src/components/layout/titlebar-overlay.ts +11 -1
  196. package/src/components/layout/window-fullscreen.ts +32 -0
  197. package/src/components/onboarding/account-step/form-panel.tsx +13 -32
  198. package/src/components/onboarding/account-step/index.tsx +13 -29
  199. package/src/components/onboarding/first-run-workspace.test.ts +81 -0
  200. package/src/components/onboarding/first-run-workspace.ts +215 -0
  201. package/src/components/onboarding/onboarding-frame.tsx +109 -35
  202. package/src/components/onboarding/onboarding-wizard.test.tsx +389 -202
  203. package/src/components/onboarding/onboarding-wizard.tsx +379 -303
  204. package/src/components/onboarding/portfolio-step/index.tsx +13 -0
  205. package/src/components/onboarding/portfolio-step/positions-panel.tsx +292 -0
  206. package/src/components/onboarding/portfolio-step/types.ts +7 -1
  207. package/src/components/onboarding/wizard-account.ts +38 -18
  208. package/src/components/onboarding/wizard-model.test.ts +67 -0
  209. package/src/components/onboarding/wizard-model.ts +99 -3
  210. package/src/components/onboarding/wizard-positions.ts +327 -0
  211. package/src/components/price-performance.tsx +1 -1
  212. package/src/components/sign-in-gate.test.tsx +10 -78
  213. package/src/components/table-view-shared.tsx +4 -3
  214. package/src/components/ticker/badge/format.test.ts +66 -0
  215. package/src/components/ticker/badge/format.ts +51 -19
  216. package/src/components/ticker/badge/index.tsx +12 -5
  217. package/src/components/ticker/badge/list.test.tsx +84 -0
  218. package/src/components/ticker/badge/list.tsx +69 -6
  219. package/src/components/ticker/list-table-view.tsx +8 -0
  220. package/src/components/ui/action-row.tsx +36 -0
  221. package/src/components/ui/button.tsx +44 -11
  222. package/src/components/ui/checkbox.tsx +5 -2
  223. package/src/components/ui/choice-dialog.tsx +15 -6
  224. package/src/components/ui/data-table/opentui/index.tsx +101 -33
  225. package/src/components/ui/data-table/stable-columns.ts +34 -0
  226. package/src/components/ui/data-table/types.ts +6 -1
  227. package/src/components/ui/display.desktop.test.tsx +55 -0
  228. package/src/components/ui/display.test.tsx +36 -0
  229. package/src/components/ui/display.tsx +124 -0
  230. package/src/components/ui/external-link.test.tsx +25 -0
  231. package/src/components/ui/external-link.tsx +11 -3
  232. package/src/components/ui/fields.tsx +17 -4
  233. package/src/components/ui/index.ts +19 -3
  234. package/src/components/ui/list-view.tsx +32 -16
  235. package/src/components/ui/loading.tsx +5 -4
  236. package/src/components/ui/native-select.tsx +14 -5
  237. package/src/components/ui/prose.tsx +110 -0
  238. package/src/components/ui/select-button.tsx +49 -18
  239. package/src/components/ui/status.tsx +63 -54
  240. package/src/components/ui/tabs.tsx +3 -1
  241. package/src/components/ui/toggle.tsx +22 -1
  242. package/src/components/ui/ui.test.tsx +62 -26
  243. package/src/components/use-pane-notice-footer.test.tsx +116 -0
  244. package/src/components/use-pane-notice-footer.tsx +128 -0
  245. package/src/core/app-runtime.test.ts +113 -0
  246. package/src/core/app-runtime.ts +97 -0
  247. package/src/core/app-services.ts +35 -103
  248. package/src/core/state/app/instrument.ts +77 -0
  249. package/src/core/state/app/layout-reducer.ts +60 -0
  250. package/src/core/state/app/layout.ts +149 -19
  251. package/src/core/state/app/state.ts +2 -2
  252. package/src/core/state/app/types.ts +14 -1
  253. package/src/core/state/session-persistence.ts +18 -48
  254. package/src/data/cached-query.test.ts +95 -0
  255. package/src/data/cached-query.ts +106 -0
  256. package/src/data/config/layout.ts +35 -1
  257. package/src/data/config/store/index.test.ts +41 -0
  258. package/src/data/config/store/normalize.ts +65 -7
  259. package/src/data/fred-series.ts +22 -66
  260. package/src/{renderers/browser/persistence.ts → data/json-persistence.ts} +8 -8
  261. package/src/{renderers/browser/storage.ts → data/json-storage.ts} +5 -5
  262. package/src/{renderers/browser/ticker-repository.ts → data/json-ticker-repository.ts} +7 -7
  263. package/src/data/memory-resource-store.test.ts +24 -0
  264. package/src/{renderers/electrobun/view/resource-store.ts → data/memory-resource-store.ts} +2 -2
  265. package/src/data/plugin-cache.test.ts +46 -0
  266. package/src/data/plugin-cache.ts +89 -0
  267. package/src/data/response-sequence.ts +6 -0
  268. package/src/i18n/es.ts +84 -3
  269. package/src/i18n/ja.ts +84 -3
  270. package/src/i18n/ko.ts +84 -3
  271. package/src/i18n/zh-cn.ts +84 -3
  272. package/src/i18n/zh-tw.ts +84 -3
  273. package/src/layout-marketplace/cloud.test.ts +154 -0
  274. package/src/layout-marketplace/cloud.ts +215 -0
  275. package/src/layout-marketplace/gallery-desktop.test.tsx +19 -74
  276. package/src/layout-marketplace/gallery-desktop.tsx +65 -3
  277. package/src/layout-marketplace/gallery-terminal.tsx +83 -5
  278. package/src/layout-marketplace/gallery.tsx +254 -18
  279. package/src/layout-marketplace/linked-sync.ts +104 -0
  280. package/src/layout-marketplace/linked.ts +119 -0
  281. package/src/layout-marketplace/mini-workspace.test.tsx +9 -62
  282. package/src/layout-marketplace/model.ts +71 -19
  283. package/src/layout-marketplace/payload.test.ts +156 -0
  284. package/src/layout-marketplace/payload.ts +77 -16
  285. package/src/layout-marketplace/use-marketplace.ts +68 -1
  286. package/src/market-data/coordinator/auxiliary.ts +40 -11
  287. package/src/market-data/coordinator/entries.ts +11 -1
  288. package/src/market-data/coordinator/events.test.ts +33 -3
  289. package/src/market-data/coordinator/events.ts +25 -1
  290. package/src/market-data/coordinator/financials.ts +2 -61
  291. package/src/market-data/coordinator/fx-refresh.test.ts +61 -0
  292. package/src/market-data/coordinator/index.test.ts +25 -0
  293. package/src/market-data/coordinator/index.ts +129 -27
  294. package/src/market-data/coordinator/quotes.ts +1 -0
  295. package/src/market-data/coordinator/subscriptions.test.ts +12 -5
  296. package/src/market-data/hooks.tsx +8 -13
  297. package/src/market-data/legacy-contract-hooks.test.tsx +49 -0
  298. package/src/market-data/legacy-contract.test.ts +99 -0
  299. package/src/market-data/market/format.test.ts +77 -1
  300. package/src/market-data/market/format.ts +100 -6
  301. package/src/market-data/market/freshness.ts +13 -1
  302. package/src/market-data/market/price-basis.ts +9 -0
  303. package/src/market-data/market/status.test.ts +15 -1
  304. package/src/market-data/market/status.ts +18 -22
  305. package/src/market-data/performance.ts +21 -6
  306. package/src/market-data/portfolio-financials.ts +27 -0
  307. package/src/market-data/portfolio-instrument.test.ts +80 -0
  308. package/src/market-data/quotes/contributions.ts +32 -9
  309. package/src/market-data/quotes/day-range.test.ts +84 -0
  310. package/src/market-data/quotes/day-range.ts +95 -0
  311. package/src/market-data/quotes/freshness.test.ts +63 -0
  312. package/src/market-data/quotes/freshness.ts +17 -11
  313. package/src/market-data/quotes/metadata.ts +55 -0
  314. package/src/market-data/quotes/observation-time.test.ts +74 -0
  315. package/src/market-data/quotes/price-basis.test.ts +44 -0
  316. package/src/market-data/quotes/resolution.test.ts +137 -0
  317. package/src/market-data/quotes/resolution.ts +57 -11
  318. package/src/market-data/request-types.ts +27 -13
  319. package/src/market-data/result-types.ts +3 -0
  320. package/src/market-data/selectors.ts +2 -23
  321. package/src/market-data/snapshot-contract.test.ts +110 -0
  322. package/src/market-data/snapshot-provider.test.ts +93 -0
  323. package/src/market-data/snapshot-provider.ts +175 -0
  324. package/src/market-data/ticker-price-returns.test.ts +26 -0
  325. package/src/market-data/ticker-price-returns.ts +18 -0
  326. package/src/news/aggregator.test.ts +20 -4
  327. package/src/news/aggregator.ts +40 -10
  328. package/src/news/news-model.ts +33 -2
  329. package/src/news/types.ts +2 -0
  330. package/src/pane-settings.ts +24 -0
  331. package/src/plugins/builtin/account-management/form-components.tsx +22 -94
  332. package/src/plugins/builtin/account-management/model.ts +26 -12
  333. package/src/plugins/builtin/account-management/navigation.ts +1 -1
  334. package/src/plugins/builtin/account-management/pane.tsx +31 -54
  335. package/src/plugins/builtin/alerts/index.test.tsx +52 -42
  336. package/src/plugins/builtin/alerts/index.tsx +7 -2
  337. package/src/plugins/builtin/alerts/quotes.ts +2 -2
  338. package/src/plugins/builtin/analytics/broker-performance.test.ts +79 -0
  339. package/src/plugins/builtin/analytics/broker-performance.ts +57 -70
  340. package/src/plugins/builtin/analytics/display.ts +6 -3
  341. package/src/plugins/builtin/analytics/index.test.tsx +262 -53
  342. package/src/plugins/builtin/analytics/index.tsx +85 -51
  343. package/src/plugins/builtin/analytics/metrics.test.ts +23 -6
  344. package/src/plugins/builtin/analytics/metrics.ts +97 -49
  345. package/src/plugins/builtin/analytics/pane-model.test.ts +191 -0
  346. package/src/plugins/builtin/analytics/pane-model.ts +194 -100
  347. package/src/plugins/builtin/analytics/portfolio-identity.test.tsx +272 -0
  348. package/src/plugins/builtin/analytics/return-window.test.ts +72 -0
  349. package/src/plugins/builtin/analytics/sector-model.test.ts +56 -0
  350. package/src/plugins/builtin/analytics/sector-model.ts +38 -23
  351. package/src/plugins/builtin/analytics/sharpe-cadence.test.ts +111 -0
  352. package/src/plugins/builtin/analytics/sharpe-cadence.ts +161 -0
  353. package/src/plugins/builtin/analytics/view.tsx +61 -66
  354. package/src/plugins/builtin/broker-manager/index.test.tsx +5 -9
  355. package/src/plugins/builtin/broker-manager/index.tsx +11 -12
  356. package/src/plugins/builtin/buildout/cells.test.tsx +31 -0
  357. package/src/plugins/builtin/buildout/cells.tsx +2 -12
  358. package/src/plugins/builtin/buildout/detail/company.tsx +23 -42
  359. package/src/plugins/builtin/buildout/detail/index.tsx +0 -1
  360. package/src/plugins/builtin/buildout/detail/intel.tsx +5 -10
  361. package/src/plugins/builtin/buildout/detail/site.tsx +15 -33
  362. package/src/plugins/builtin/buildout/detail/ui.tsx +17 -56
  363. package/src/plugins/builtin/buildout/pane/header.tsx +3 -11
  364. package/src/plugins/builtin/buildout/pane/status.tsx +3 -18
  365. package/src/plugins/builtin/cds/headless.test.ts +20 -2
  366. package/src/plugins/builtin/cds/model.test.ts +10 -0
  367. package/src/plugins/builtin/cds/model.ts +18 -8
  368. package/src/plugins/builtin/cds/pane.test.tsx +2 -2
  369. package/src/plugins/builtin/cds/pane.tsx +32 -41
  370. package/src/plugins/builtin/chart-composer/catalog-inventory.test.ts +17 -0
  371. package/src/plugins/builtin/chart-composer/catalog-inventory.ts +57 -16
  372. package/src/plugins/builtin/chart-composer/cli-options.ts +7 -4
  373. package/src/plugins/builtin/chart-composer/data-catalog-pane.tsx +24 -2
  374. package/src/plugins/builtin/chart-composer/editor/controller.ts +7 -1
  375. package/src/plugins/builtin/chart-composer/editor/opentui-view.tsx +2 -0
  376. package/src/plugins/builtin/chart-composer/editor.test.tsx +32 -23
  377. package/src/plugins/builtin/chart-composer/editor.tsx +3 -6
  378. package/src/plugins/builtin/chart-composer/financial-periods.fixture.json +225 -0
  379. package/src/plugins/builtin/chart-composer/headless-schema.ts +221 -0
  380. package/src/plugins/builtin/chart-composer/headless.test.ts +158 -0
  381. package/src/plugins/builtin/chart-composer/headless.ts +225 -0
  382. package/src/plugins/builtin/chart-composer/index.tsx +90 -8
  383. package/src/plugins/builtin/chart-composer/loading.test.tsx +134 -0
  384. package/src/plugins/builtin/chart-composer/pane-share.test.ts +74 -1
  385. package/src/plugins/builtin/chart-composer/pane.tsx +125 -134
  386. package/src/plugins/builtin/chart-composer/presets.test.ts +46 -0
  387. package/src/plugins/builtin/chart-composer/presets.ts +41 -13
  388. package/src/plugins/builtin/chart-composer/quick-add.tsx +7 -1
  389. package/src/plugins/builtin/chart-composer/quote-metadata.test.ts +176 -0
  390. package/src/plugins/builtin/chart-composer/semantic.ts +1 -0
  391. package/src/plugins/builtin/chart-composer/settings.test.ts +30 -0
  392. package/src/plugins/builtin/chart-composer/settings.ts +1 -1
  393. package/src/plugins/builtin/chart-composer/use-series-catalog.test.tsx +94 -0
  394. package/src/plugins/builtin/chart-composer/use-series-catalog.ts +7 -2
  395. package/src/plugins/builtin/chat/channel-labels.ts +13 -0
  396. package/src/plugins/builtin/chat/channels.ts +2 -0
  397. package/src/plugins/builtin/chat/content/channel-navigation.ts +16 -3
  398. package/src/plugins/builtin/chat/content/composer.tsx +13 -46
  399. package/src/plugins/builtin/chat/content/index.tsx +3 -1
  400. package/src/plugins/builtin/chat/content/new-dm-dialog.tsx +10 -15
  401. package/src/plugins/builtin/chat/controller/channels.ts +5 -1
  402. package/src/plugins/builtin/chat/controller/index.ts +17 -4
  403. package/src/plugins/builtin/chat/controller/session-lifetime.test.ts +182 -0
  404. package/src/plugins/builtin/chat/controller/session-runtime.ts +16 -4
  405. package/src/plugins/builtin/chat/controller.test.ts +173 -296
  406. package/src/plugins/builtin/chat/message/desktop.tsx +9 -9
  407. package/src/plugins/builtin/chat/message/profile-popover.tsx +3 -23
  408. package/src/plugins/builtin/chat/message/terminal.tsx +9 -9
  409. package/src/plugins/builtin/chat/sidebar.test.tsx +107 -0
  410. package/src/plugins/builtin/chat/sidebar.tsx +71 -18
  411. package/src/plugins/builtin/chat/status-widget.tsx +6 -12
  412. package/src/plugins/builtin/chat/test-harness.test.ts +46 -0
  413. package/src/plugins/builtin/chat/test-harness.tsx +12 -6
  414. package/src/plugins/builtin/cloud/askg/controller.test.ts +275 -0
  415. package/src/plugins/builtin/cloud/askg/controller.ts +440 -0
  416. package/src/plugins/builtin/cloud/askg/host.ts +87 -0
  417. package/src/plugins/builtin/cloud/askg/model.test.ts +222 -0
  418. package/src/plugins/builtin/cloud/askg/model.ts +623 -0
  419. package/src/plugins/builtin/cloud/askg/pane.tsx +734 -0
  420. package/src/plugins/builtin/cloud/askg/pending-question.ts +38 -0
  421. package/src/plugins/builtin/cloud/askg/protocol.ts +11 -0
  422. package/src/plugins/builtin/cloud/auth-actions.tsx +49 -51
  423. package/src/plugins/builtin/cloud/auth-form.tsx +5 -7
  424. package/src/plugins/builtin/cloud/auth-model.ts +8 -6
  425. package/src/plugins/builtin/cloud/plugin.tsx +57 -3
  426. package/src/plugins/builtin/cloud/team/acm-tab.tsx +127 -0
  427. package/src/plugins/builtin/cloud/team/capability.ts +71 -0
  428. package/src/plugins/builtin/cloud/team/collections-sync.ts +222 -0
  429. package/src/plugins/builtin/cloud/team/collections.test.ts +126 -0
  430. package/src/plugins/builtin/cloud/team/collections.ts +181 -0
  431. package/src/plugins/builtin/cloud/team/command.ts +313 -0
  432. package/src/plugins/builtin/cloud/team/model.test.ts +174 -0
  433. package/src/plugins/builtin/cloud/team/model.ts +209 -0
  434. package/src/plugins/builtin/cloud/team/module.tsx +78 -0
  435. package/src/plugins/builtin/cloud/team/pane-model.test.ts +100 -0
  436. package/src/plugins/builtin/cloud/team/pane-model.ts +156 -0
  437. package/src/plugins/builtin/cloud/team/pane-request.ts +47 -0
  438. package/src/plugins/builtin/cloud/team/pane-sections.tsx +509 -0
  439. package/src/plugins/builtin/cloud/team/pane-ui.tsx +325 -0
  440. package/src/plugins/builtin/cloud/team/pane.test.tsx +196 -0
  441. package/src/plugins/builtin/cloud/team/pane.tsx +712 -0
  442. package/src/plugins/builtin/cloud/team/status-widget.tsx +75 -0
  443. package/src/plugins/builtin/cloud/team/store.test.ts +231 -0
  444. package/src/plugins/builtin/cloud/team/store.ts +318 -0
  445. package/src/plugins/builtin/cloud/team/team-state-host.ts +70 -0
  446. package/src/plugins/builtin/cloud/team/views.ts +185 -0
  447. package/src/plugins/builtin/cloud/thesis/board-pane.test.tsx +239 -0
  448. package/src/plugins/builtin/cloud/thesis/board-pane.tsx +471 -0
  449. package/src/plugins/builtin/cloud/thesis/detail.tsx +522 -0
  450. package/src/plugins/builtin/cloud/thesis/exposure.ts +119 -0
  451. package/src/plugins/builtin/cloud/thesis/flows.ts +552 -0
  452. package/src/plugins/builtin/cloud/thesis/model.test.ts +171 -0
  453. package/src/plugins/builtin/cloud/thesis/model.ts +406 -0
  454. package/src/plugins/builtin/cloud/thesis/module.tsx +63 -0
  455. package/src/plugins/builtin/cloud/thesis/pane-request.ts +47 -0
  456. package/src/plugins/builtin/cloud/thesis/prompts.tsx +214 -0
  457. package/src/plugins/builtin/cloud/thesis/store.ts +279 -0
  458. package/src/plugins/builtin/cloud/thesis/ticker-tab.tsx +131 -0
  459. package/src/plugins/builtin/cloud/upgrade-status-widget.tsx +2 -15
  460. package/src/plugins/builtin/cloud/verification-status-widget.tsx +72 -0
  461. package/src/plugins/builtin/cloud-tweets/model.ts +13 -0
  462. package/src/plugins/builtin/cloud-tweets/pane.tsx +4 -2
  463. package/src/plugins/builtin/cloud-tweets/table.test.tsx +125 -0
  464. package/src/plugins/builtin/cloud-tweets/table.tsx +66 -20
  465. package/src/plugins/builtin/composite-plugins.ts +2 -12
  466. package/src/plugins/builtin/congress-trades/detail.tsx +42 -7
  467. package/src/plugins/builtin/congress-trades/footer.ts +23 -7
  468. package/src/plugins/builtin/congress-trades/keyboard.ts +10 -1
  469. package/src/plugins/builtin/congress-trades/model.test.ts +29 -10
  470. package/src/plugins/builtin/congress-trades/model.ts +28 -3
  471. package/src/plugins/builtin/congress-trades/pane.tsx +24 -6
  472. package/src/plugins/builtin/congress-trades/table.tsx +0 -1
  473. package/src/plugins/builtin/connections/pane.test.tsx +12 -16
  474. package/src/plugins/builtin/connections/pane.tsx +18 -30
  475. package/src/plugins/builtin/correlation/compute.test.ts +53 -86
  476. package/src/plugins/builtin/correlation/compute.ts +54 -60
  477. package/src/plugins/builtin/correlation/headless-schema.ts +69 -0
  478. package/src/plugins/builtin/correlation/headless.test.ts +147 -0
  479. package/src/plugins/builtin/correlation/headless.ts +110 -0
  480. package/src/plugins/builtin/correlation/history.ts +16 -0
  481. package/src/plugins/builtin/correlation/index.test.tsx +27 -55
  482. package/src/plugins/builtin/correlation/index.tsx +31 -13
  483. package/src/plugins/builtin/correlation/matrix/model.ts +38 -21
  484. package/src/plugins/builtin/correlation/relationship/controls.tsx +0 -30
  485. package/src/plugins/builtin/correlation/relationship/history.test.tsx +62 -0
  486. package/src/plugins/builtin/correlation/relationship/history.ts +31 -57
  487. package/src/plugins/builtin/correlation/relationship/model.ts +29 -62
  488. package/src/plugins/builtin/correlation/relationship/pane.tsx +47 -38
  489. package/src/plugins/builtin/credit-conditions/client.test.ts +43 -1
  490. package/src/plugins/builtin/credit-conditions/client.ts +17 -6
  491. package/src/plugins/builtin/credit-conditions/index.test.tsx +59 -38
  492. package/src/plugins/builtin/credit-conditions/index.tsx +35 -60
  493. package/src/plugins/builtin/credit-conditions/model.test.ts +1 -0
  494. package/src/plugins/builtin/credit-conditions/model.ts +1 -0
  495. package/src/plugins/builtin/custom-view/index.tsx +69 -0
  496. package/src/plugins/builtin/custom-view/loader.ts +107 -0
  497. package/src/plugins/builtin/custom-view/pane.tsx +308 -0
  498. package/src/plugins/builtin/custom-view/view-spec.test.ts +107 -0
  499. package/src/plugins/builtin/custom-view/view-spec.ts +347 -0
  500. package/src/plugins/builtin/debug/index.tsx +65 -46
  501. package/src/plugins/builtin/debug/template.ts +8 -0
  502. package/src/plugins/builtin/dividend-yield/browser.tsx +26 -0
  503. package/src/plugins/builtin/dividend-yield/calendar.ts +9 -0
  504. package/src/plugins/builtin/dividend-yield/client.test.ts +204 -2
  505. package/src/plugins/builtin/dividend-yield/client.ts +148 -96
  506. package/src/plugins/builtin/dividend-yield/dividend-source-integrity.test.ts +232 -0
  507. package/src/plugins/builtin/dividend-yield/headless.test.ts +35 -1
  508. package/src/plugins/builtin/dividend-yield/headless.ts +48 -11
  509. package/src/plugins/builtin/dividend-yield/index.tsx +64 -51
  510. package/src/plugins/builtin/dividend-yield/pane.test.tsx +349 -0
  511. package/src/plugins/builtin/dividend-yield/pane.tsx +118 -117
  512. package/src/plugins/builtin/dividend-yield/provider-client.test.ts +61 -0
  513. package/src/plugins/builtin/dividend-yield/provider-client.ts +44 -0
  514. package/src/plugins/builtin/dividend-yield/reference-price.test.ts +115 -0
  515. package/src/plugins/builtin/dividend-yield/reference-price.ts +27 -0
  516. package/src/plugins/builtin/dividend-yield/view.test.ts +58 -0
  517. package/src/plugins/builtin/dividend-yield/view.ts +35 -0
  518. package/src/plugins/builtin/earnings/data/cache.test.ts +21 -1
  519. package/src/plugins/builtin/earnings/data/cache.ts +11 -86
  520. package/src/plugins/builtin/earnings/detail-model.test.ts +103 -0
  521. package/src/plugins/builtin/earnings/detail-model.ts +165 -0
  522. package/src/plugins/builtin/earnings/detail-view.tsx +131 -0
  523. package/src/plugins/builtin/earnings/estimate-basis.test.ts +158 -0
  524. package/src/plugins/builtin/earnings/estimate-basis.ts +76 -0
  525. package/src/plugins/builtin/earnings/estimate-fixtures.test-data.ts +327 -0
  526. package/src/plugins/builtin/earnings/headless.ts +29 -18
  527. package/src/plugins/builtin/earnings/index.tsx +114 -63
  528. package/src/plugins/builtin/earnings/model.test.ts +29 -1
  529. package/src/plugins/builtin/earnings/table.test.ts +60 -0
  530. package/src/plugins/builtin/earnings/table.ts +46 -36
  531. package/src/plugins/builtin/earnings-calls/data.test.ts +252 -0
  532. package/src/plugins/builtin/earnings-calls/data.ts +66 -28
  533. package/src/plugins/builtin/earnings-calls/headless-freshness.test.ts +41 -0
  534. package/src/plugins/builtin/earnings-calls/headless.test.ts +69 -3
  535. package/src/plugins/builtin/earnings-calls/headless.ts +82 -89
  536. package/src/plugins/builtin/earnings-calls/index.tsx +22 -22
  537. package/src/plugins/builtin/earnings-calls/model.ts +1 -0
  538. package/src/plugins/builtin/earnings-calls/pane.test.tsx +466 -0
  539. package/src/plugins/builtin/earnings-calls/pane.tsx +225 -65
  540. package/src/plugins/builtin/earnings-calls/prose.test.ts +16 -1
  541. package/src/plugins/builtin/earnings-calls/prose.ts +33 -30
  542. package/src/plugins/builtin/earnings-calls/transcript-view.tsx +138 -115
  543. package/src/plugins/builtin/econ/calendar-model.ts +10 -61
  544. package/src/plugins/builtin/econ/detail-view.tsx +35 -81
  545. package/src/plugins/builtin/econ/fred-cache.test.ts +39 -1
  546. package/src/plugins/builtin/econ/fred-client.test.ts +34 -7
  547. package/src/plugins/builtin/econ/fred-series-map.ts +57 -36
  548. package/src/plugins/builtin/econ/index.test.tsx +10 -13
  549. package/src/plugins/builtin/econ-statistics/client.test.ts +108 -0
  550. package/src/plugins/builtin/econ-statistics/client.ts +42 -13
  551. package/src/plugins/builtin/econ-statistics/defs.ts +3 -0
  552. package/src/plugins/builtin/econ-statistics/detail.tsx +12 -13
  553. package/src/plugins/builtin/econ-statistics/headless.test.ts +1 -1
  554. package/src/plugins/builtin/econ-statistics/headless.ts +6 -1
  555. package/src/plugins/builtin/econ-statistics/pane.test.tsx +69 -0
  556. package/src/plugins/builtin/econ-statistics/pane.tsx +52 -87
  557. package/src/plugins/builtin/econ-statistics/stats.ts +30 -11
  558. package/src/plugins/builtin/econ-statistics/transform.test.ts +23 -0
  559. package/src/plugins/builtin/econ-statistics/transform.ts +13 -4
  560. package/src/plugins/builtin/econ-statistics/view.test.ts +27 -0
  561. package/src/plugins/builtin/econ-statistics/view.ts +20 -1
  562. package/src/plugins/builtin/executives/data.ts +126 -0
  563. package/src/plugins/builtin/executives/format.test.ts +23 -0
  564. package/src/plugins/builtin/executives/format.ts +58 -0
  565. package/src/plugins/builtin/executives/index.tsx +61 -0
  566. package/src/plugins/builtin/executives/pane.test.tsx +335 -0
  567. package/src/plugins/builtin/executives/pane.tsx +467 -0
  568. package/src/plugins/builtin/filing-events/feed.test.ts +146 -0
  569. package/src/plugins/builtin/filing-events/feed.ts +189 -0
  570. package/src/plugins/builtin/filing-events/index.tsx +50 -0
  571. package/src/plugins/builtin/filing-events/pane.test.tsx +107 -0
  572. package/src/plugins/builtin/filing-events/pane.tsx +253 -0
  573. package/src/plugins/builtin/futures/index.tsx +15 -8
  574. package/src/plugins/builtin/futures/model.test.ts +25 -0
  575. package/src/plugins/builtin/futures/model.ts +12 -3
  576. package/src/plugins/builtin/futures/pane.test.tsx +8 -28
  577. package/src/plugins/builtin/futures/table.tsx +2 -2
  578. package/src/plugins/builtin/fx-matrix/export.test.ts +30 -0
  579. package/src/plugins/builtin/fx-matrix/export.ts +32 -0
  580. package/src/plugins/builtin/fx-matrix/index.tsx +24 -41
  581. package/src/plugins/builtin/fx-matrix/pairs.test.ts +11 -0
  582. package/src/plugins/builtin/fx-matrix/pairs.ts +3 -2
  583. package/src/plugins/builtin/fx-matrix/pane.test.tsx +6 -9
  584. package/src/plugins/builtin/fx-matrix/refresh.test.tsx +69 -0
  585. package/src/plugins/builtin/help/components.tsx +6 -26
  586. package/src/plugins/builtin/help/index.tsx +34 -44
  587. package/src/plugins/builtin/holders/headless.ts +8 -0
  588. package/src/plugins/builtin/insider/amendments.test.ts +112 -0
  589. package/src/plugins/builtin/insider/amendments.ts +65 -0
  590. package/src/plugins/builtin/insider/client.ts +4 -8
  591. package/src/plugins/builtin/insider/headless.test.ts +14 -0
  592. package/src/plugins/builtin/insider/headless.ts +27 -5
  593. package/src/plugins/builtin/insider/index.tsx +70 -36
  594. package/src/plugins/builtin/insider/insider-data.test.ts +50 -37
  595. package/src/plugins/builtin/insider/insider-data.ts +100 -31
  596. package/src/plugins/builtin/insider/model.ts +102 -55
  597. package/src/plugins/builtin/insider/pane.test.tsx +87 -0
  598. package/src/plugins/builtin/jobs/client.ts +85 -0
  599. package/src/plugins/builtin/jobs/headless.ts +215 -0
  600. package/src/plugins/builtin/jobs/index.tsx +83 -0
  601. package/src/plugins/builtin/jobs/model.test.ts +119 -0
  602. package/src/plugins/builtin/jobs/model.ts +350 -0
  603. package/src/plugins/builtin/jobs/pages.test.tsx +103 -0
  604. package/src/plugins/builtin/jobs/pages.ts +48 -0
  605. package/src/plugins/builtin/jobs/pane.tsx +710 -0
  606. package/src/plugins/builtin/jobs/share-bars.tsx +93 -0
  607. package/src/plugins/builtin/kelly-sizer/model.test.ts +6 -0
  608. package/src/plugins/builtin/kelly-sizer/model.ts +2 -2
  609. package/src/plugins/builtin/kelly-sizer/pane.tsx +21 -13
  610. package/src/plugins/builtin/kelly-sizer/portfolio.ts +9 -11
  611. package/src/plugins/builtin/kelly-sizer/sections.tsx +17 -23
  612. package/src/plugins/builtin/kelly-sizer/view.test.tsx +11 -0
  613. package/src/plugins/builtin/kelly-sizer/view.tsx +20 -58
  614. package/src/plugins/builtin/market-movers/headless.ts +9 -8
  615. package/src/plugins/builtin/market-movers/index.tsx +26 -21
  616. package/src/plugins/builtin/market-movers/integrity.test.ts +119 -0
  617. package/src/plugins/builtin/market-movers/model.ts +44 -10
  618. package/src/plugins/builtin/market-movers/pane-research.test.tsx +138 -0
  619. package/src/plugins/builtin/market-movers/screener.ts +77 -51
  620. package/src/plugins/builtin/market-movers/table.ts +12 -12
  621. package/src/plugins/builtin/market-valuation/align.ts +28 -17
  622. package/src/plugins/builtin/market-valuation/cache.ts +9 -1
  623. package/src/plugins/builtin/market-valuation/chart-projection.ts +11 -9
  624. package/src/plugins/builtin/market-valuation/chart-series.ts +14 -4
  625. package/src/plugins/builtin/market-valuation/client.test.ts +160 -21
  626. package/src/plugins/builtin/market-valuation/client.ts +54 -16
  627. package/src/plugins/builtin/market-valuation/defs.ts +13 -1
  628. package/src/plugins/builtin/market-valuation/detail.tsx +25 -43
  629. package/src/plugins/builtin/market-valuation/headless.test.ts +19 -2
  630. package/src/plugins/builtin/market-valuation/headless.ts +11 -6
  631. package/src/plugins/builtin/market-valuation/indicators.ts +51 -84
  632. package/src/plugins/builtin/market-valuation/model.test.ts +79 -43
  633. package/src/plugins/builtin/market-valuation/pane.test.tsx +47 -53
  634. package/src/plugins/builtin/market-valuation/pane.tsx +87 -100
  635. package/src/plugins/builtin/market-valuation/series.ts +18 -1
  636. package/src/plugins/builtin/market-valuation/sources.ts +74 -10
  637. package/src/plugins/builtin/market-valuation/trend.ts +2 -4
  638. package/src/plugins/builtin/market-valuation/view.ts +26 -23
  639. package/src/plugins/builtin/news/index.tsx +8 -3
  640. package/src/plugins/builtin/news/wire/breaking/pane.test.tsx +13 -41
  641. package/src/plugins/builtin/news/wire/breaking/pane.tsx +7 -3
  642. package/src/plugins/builtin/news/wire/index.tsx +30 -9
  643. package/src/plugins/builtin/news/wire/industry-pane.tsx +7 -3
  644. package/src/plugins/builtin/news/wire/news/detail-view.test.tsx +279 -0
  645. package/src/plugins/builtin/news/wire/news/detail-view.tsx +91 -47
  646. package/src/plugins/builtin/news/wire/news/footer.ts +17 -22
  647. package/src/plugins/builtin/news/wire/news/preset-pane.tsx +7 -3
  648. package/src/plugins/builtin/news/wire/news/table.tsx +11 -1
  649. package/src/plugins/builtin/news/wire/persisted-articles.ts +23 -2
  650. package/src/plugins/builtin/news/wire/rss/feed-xml.ts +104 -0
  651. package/src/plugins/builtin/news/wire/rss/parser.test.ts +63 -1
  652. package/src/plugins/builtin/news/wire/rss/parser.ts +70 -96
  653. package/src/plugins/builtin/news/wire/rss/source.test.ts +38 -1
  654. package/src/plugins/builtin/news/wire/rss/source.ts +26 -25
  655. package/src/plugins/builtin/notes/export.ts +57 -0
  656. package/src/plugins/builtin/notes/files.ts +6 -1
  657. package/src/plugins/builtin/notes/index.tsx +85 -10
  658. package/src/plugins/builtin/notes/migration.ts +80 -0
  659. package/src/plugins/builtin/notes/owner.tsx +129 -0
  660. package/src/plugins/builtin/notes/quick-notes-pane.test.tsx +10 -2
  661. package/src/plugins/builtin/notes/quick-notes-pane.tsx +130 -42
  662. package/src/plugins/builtin/notes/store.test.ts +245 -0
  663. package/src/plugins/builtin/notes/store.ts +304 -0
  664. package/src/plugins/builtin/notes/ticker-notes-tab.test.tsx +38 -68
  665. package/src/plugins/builtin/notes/ticker-notes-tab.tsx +60 -13
  666. package/src/plugins/builtin/options/analytics.test.ts +65 -0
  667. package/src/plugins/builtin/options/analytics.ts +62 -23
  668. package/src/plugins/builtin/options/calc-seed.test.ts +15 -3
  669. package/src/plugins/builtin/options/calc-seed.ts +18 -6
  670. package/src/plugins/builtin/options/chain-integrity.test.tsx +251 -0
  671. package/src/plugins/builtin/options/expiry-catalogue.ts +43 -0
  672. package/src/plugins/builtin/options/expiry-selection.test.tsx +317 -0
  673. package/src/plugins/builtin/options/footer.test.ts +38 -1
  674. package/src/plugins/builtin/options/footer.ts +69 -3
  675. package/src/plugins/builtin/options/live-quotes.test.ts +18 -4
  676. package/src/plugins/builtin/options/live-quotes.ts +7 -2
  677. package/src/plugins/builtin/options/market-reference.test.ts +36 -0
  678. package/src/plugins/builtin/options/market-reference.ts +70 -0
  679. package/src/plugins/builtin/options/quote-context.tsx +29 -0
  680. package/src/plugins/builtin/options/table.test.ts +100 -0
  681. package/src/plugins/builtin/options/table.ts +41 -11
  682. package/src/plugins/builtin/options/types.ts +1 -0
  683. package/src/plugins/builtin/options/view.test.tsx +271 -43
  684. package/src/plugins/builtin/options/view.tsx +137 -65
  685. package/src/plugins/builtin/options-calculator/boundary-integrity.test.tsx +112 -0
  686. package/src/plugins/builtin/options-calculator/index.tsx +1 -1
  687. package/src/plugins/builtin/options-calculator/model.test.ts +70 -0
  688. package/src/plugins/builtin/options-calculator/model.ts +52 -6
  689. package/src/plugins/builtin/options-calculator/pane.test.tsx +44 -12
  690. package/src/plugins/builtin/options-calculator/pane.tsx +59 -61
  691. package/src/plugins/builtin/plugin-marketplace/ids.ts +2 -0
  692. package/src/plugins/builtin/plugin-marketplace/model.test.ts +238 -19
  693. package/src/plugins/builtin/plugin-marketplace/model.ts +219 -17
  694. package/src/plugins/builtin/plugin-marketplace/pane.tsx +426 -198
  695. package/src/plugins/builtin/plugin-marketplace/store.ts +56 -6
  696. package/src/plugins/builtin/plugin-module.ts +9 -6
  697. package/src/plugins/builtin/portfolio-list/account-metrics.test.ts +20 -0
  698. package/src/plugins/builtin/portfolio-list/account-metrics.ts +3 -4
  699. package/src/plugins/builtin/portfolio-list/bond-price-basis.test.ts +120 -0
  700. package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +1 -1
  701. package/src/plugins/builtin/portfolio-list/cli/render.test.ts +261 -0
  702. package/src/plugins/builtin/portfolio-list/cli/render.ts +81 -27
  703. package/src/plugins/builtin/portfolio-list/cli/shared.ts +1 -1
  704. package/src/plugins/builtin/portfolio-list/column-values.ts +87 -123
  705. package/src/plugins/builtin/portfolio-list/command-bar.ts +1 -1
  706. package/src/plugins/builtin/portfolio-list/grid.tsx +3 -1
  707. package/src/plugins/builtin/portfolio-list/header.tsx +7 -41
  708. package/src/plugins/builtin/portfolio-list/metrics.test.ts +133 -1
  709. package/src/plugins/builtin/portfolio-list/mutations.test.ts +13 -0
  710. package/src/plugins/builtin/portfolio-list/mutations.ts +7 -1
  711. package/src/plugins/builtin/portfolio-list/pane/data.ts +4 -0
  712. package/src/plugins/builtin/portfolio-list/pane/index.test.tsx +153 -88
  713. package/src/plugins/builtin/portfolio-list/pane/index.tsx +43 -10
  714. package/src/plugins/builtin/portfolio-list/pane/streaming.ts +22 -8
  715. package/src/plugins/builtin/portfolio-list/position-cost-integrity.test.ts +101 -0
  716. package/src/plugins/builtin/portfolio-list/position-metrics.ts +166 -90
  717. package/src/plugins/builtin/portfolio-list/summary/index.tsx +31 -3
  718. package/src/plugins/builtin/portfolio-list/summary/totals.ts +71 -31
  719. package/src/plugins/builtin/portfolio-list/table.tsx +15 -1
  720. package/src/plugins/builtin/portfolio-list/use-cursor-neighbor-prefetch.test.tsx +96 -0
  721. package/src/plugins/builtin/portfolio-list/use-cursor-neighbor-prefetch.ts +87 -0
  722. package/src/plugins/builtin/portfolio-list/use-throttled-cursor-symbol.test.tsx +8 -5
  723. package/src/plugins/builtin/portfolio-list/use-throttled-cursor-symbol.ts +4 -1
  724. package/src/plugins/builtin/research/analyst-headless.test.ts +28 -0
  725. package/src/plugins/builtin/research/analyst-headless.ts +26 -22
  726. package/src/plugins/builtin/research/analyst-model.test.ts +36 -0
  727. package/src/plugins/builtin/research/analyst-model.ts +61 -17
  728. package/src/plugins/builtin/research/analyst-pane.test.tsx +120 -0
  729. package/src/plugins/builtin/research/analyst-pane.tsx +15 -7
  730. package/src/plugins/builtin/research/corporate-actions-pane.test.tsx +68 -0
  731. package/src/plugins/builtin/research/corporate-actions-pane.tsx +122 -29
  732. package/src/plugins/builtin/research/equity-diagnostic-pane.test.tsx +17 -46
  733. package/src/plugins/builtin/research/equity-diagnostic-pane.tsx +13 -24
  734. package/src/plugins/builtin/research/event-model.test.ts +137 -0
  735. package/src/plugins/builtin/research/event-model.ts +173 -33
  736. package/src/plugins/builtin/research/events-headless.test.ts +11 -0
  737. package/src/plugins/builtin/research/events-headless.ts +36 -19
  738. package/src/plugins/builtin/research/headless-schema.ts +16 -0
  739. package/src/plugins/builtin/research/headless.test.ts +18 -0
  740. package/src/plugins/builtin/research/headless.ts +19 -8
  741. package/src/plugins/builtin/research/index.test.ts +73 -5
  742. package/src/plugins/builtin/research/index.tsx +3 -0
  743. package/src/plugins/builtin/research/relative-valuation-headless.test.ts +192 -0
  744. package/src/plugins/builtin/research/relative-valuation-headless.ts +51 -0
  745. package/src/plugins/builtin/research/relative-valuation-model.ts +54 -0
  746. package/src/plugins/builtin/research/relative-valuation-pane.test.tsx +98 -0
  747. package/src/plugins/builtin/research/relative-valuation-pane.tsx +72 -71
  748. package/src/plugins/builtin/research-search/document-view.tsx +15 -28
  749. package/src/plugins/builtin/research-search/pane.test.tsx +11 -20
  750. package/src/plugins/builtin/research-search/pane.tsx +5 -9
  751. package/src/plugins/builtin/risk-factors/data.test.ts +53 -0
  752. package/src/plugins/builtin/risk-factors/data.ts +117 -0
  753. package/src/plugins/builtin/risk-factors/headless.test.ts +40 -0
  754. package/src/plugins/builtin/risk-factors/headless.ts +70 -0
  755. package/src/plugins/builtin/risk-factors/index.tsx +63 -0
  756. package/src/plugins/builtin/risk-factors/pane.test.tsx +52 -0
  757. package/src/plugins/builtin/risk-factors/pane.tsx +310 -0
  758. package/src/plugins/builtin/risk-factors/test-fixtures.ts +4 -0
  759. package/src/plugins/builtin/scanner/denied.tsx +7 -7
  760. package/src/plugins/builtin/scanner/feed.ts +2 -2
  761. package/src/plugins/builtin/scanner/flow-pane.tsx +17 -8
  762. package/src/plugins/builtin/scanner/hilo-pane.tsx +21 -7
  763. package/src/plugins/builtin/sec/filing-content.test.ts +16 -0
  764. package/src/plugins/builtin/sec/filing-content.ts +46 -5
  765. package/src/plugins/builtin/sec/filing-display.tsx +13 -7
  766. package/src/plugins/builtin/sec/filing-documents.ts +10 -0
  767. package/src/plugins/builtin/sec/headless.test.ts +27 -0
  768. package/src/plugins/builtin/sec/headless.ts +4 -2
  769. package/src/plugins/builtin/sec/index.tsx +125 -29
  770. package/src/plugins/builtin/sec/model.ts +41 -3
  771. package/src/plugins/builtin/sec/pane.test.tsx +152 -0
  772. package/src/plugins/builtin/sectors/client.test.ts +211 -0
  773. package/src/plugins/builtin/sectors/client.ts +89 -18
  774. package/src/plugins/builtin/sectors/headless.test.ts +59 -0
  775. package/src/plugins/builtin/sectors/headless.ts +20 -1
  776. package/src/plugins/builtin/sectors/index.tsx +21 -22
  777. package/src/plugins/builtin/sectors/pane-cache.test.tsx +78 -0
  778. package/src/plugins/builtin/sectors/sector-model.test.ts +59 -0
  779. package/src/plugins/builtin/sectors/sector-model.ts +89 -24
  780. package/src/plugins/builtin/shared/cloud-upgrade.ts +49 -15
  781. package/src/plugins/builtin/shared/headless-market-data.ts +40 -0
  782. package/src/plugins/builtin/shared/headless-options.ts +33 -0
  783. package/src/plugins/builtin/shared/pane-footer.ts +4 -6
  784. package/src/plugins/builtin/shared/research-cloud-session.test.tsx +143 -0
  785. package/src/plugins/builtin/shared/research-cloud-session.ts +16 -0
  786. package/src/plugins/builtin/shared/screener-live-quotes.test.ts +13 -0
  787. package/src/plugins/builtin/shared/screener-live-quotes.ts +10 -9
  788. package/src/plugins/builtin/shared/series-cache.test.ts +106 -0
  789. package/src/plugins/builtin/shared/series-cache.ts +94 -49
  790. package/src/plugins/builtin/shared/table-pane.ts +4 -1
  791. package/src/plugins/builtin/shared/ticker-request.test.tsx +137 -0
  792. package/src/plugins/builtin/shared/ticker-request.ts +11 -46
  793. package/src/plugins/builtin/shared/ticker-surface.test.ts +1 -1
  794. package/src/plugins/builtin/shared/ticker-surface.ts +4 -3
  795. package/src/plugins/builtin/shared/use-quote-board.test.tsx +73 -6
  796. package/src/plugins/builtin/shared/use-quote-board.ts +18 -10
  797. package/src/plugins/builtin/short-interest/client.test.ts +47 -0
  798. package/src/plugins/builtin/short-interest/client.ts +5 -10
  799. package/src/plugins/builtin/short-interest/model.ts +13 -4
  800. package/src/plugins/builtin/short-interest/pane.test.tsx +57 -0
  801. package/src/plugins/builtin/short-interest/pane.tsx +21 -69
  802. package/src/plugins/builtin/thirteenf/api.test.ts +91 -0
  803. package/src/plugins/builtin/thirteenf/api.ts +78 -88
  804. package/src/plugins/builtin/thirteenf/data.test.ts +177 -1
  805. package/src/plugins/builtin/thirteenf/data.ts +118 -38
  806. package/src/plugins/builtin/thirteenf/format.ts +2 -0
  807. package/src/plugins/builtin/thirteenf/headless.test.ts +36 -0
  808. package/src/plugins/builtin/thirteenf/headless.ts +27 -8
  809. package/src/plugins/builtin/thirteenf/model.test.ts +90 -24
  810. package/src/plugins/builtin/thirteenf/model.ts +129 -82
  811. package/src/plugins/builtin/thirteenf/pane.test.tsx +27 -92
  812. package/src/plugins/builtin/thirteenf/pane.tsx +55 -33
  813. package/src/plugins/builtin/thirteenf/table.ts +2 -3
  814. package/src/plugins/builtin/thirteenf/types.ts +13 -1
  815. package/src/plugins/builtin/ticker-detail/chart-tab-switch.test.tsx +17 -50
  816. package/src/plugins/builtin/ticker-detail/data-panes/historical-price-precision.test.tsx +120 -0
  817. package/src/plugins/builtin/ticker-detail/data-panes/historical-prices.test.tsx +41 -0
  818. package/src/plugins/builtin/ticker-detail/data-panes/historical-prices.tsx +36 -13
  819. package/src/plugins/builtin/ticker-detail/financials/aggregation.test.ts +79 -0
  820. package/src/plugins/builtin/ticker-detail/financials/aggregation.ts +90 -13
  821. package/src/plugins/builtin/ticker-detail/financials/model.test.ts +152 -0
  822. package/src/plugins/builtin/ticker-detail/financials/model.ts +139 -22
  823. package/src/plugins/builtin/ticker-detail/financials/period-integrity.test.tsx +77 -0
  824. package/src/plugins/builtin/ticker-detail/financials/schema.ts +3 -3
  825. package/src/plugins/builtin/ticker-detail/financials/tab.tsx +71 -49
  826. package/src/plugins/builtin/ticker-detail/fund-profile.test.tsx +118 -0
  827. package/src/plugins/builtin/ticker-detail/headless-schema.ts +59 -0
  828. package/src/plugins/builtin/ticker-detail/headless.test.ts +165 -0
  829. package/src/plugins/builtin/ticker-detail/headless.ts +150 -0
  830. package/src/plugins/builtin/ticker-detail/index.tsx +34 -22
  831. package/src/plugins/builtin/ticker-detail/overview/components.tsx +21 -22
  832. package/src/plugins/builtin/ticker-detail/overview/model.test.ts +118 -0
  833. package/src/plugins/builtin/ticker-detail/overview/model.ts +65 -43
  834. package/src/plugins/builtin/ticker-detail/overview/pane.tsx +2 -1
  835. package/src/plugins/builtin/ticker-detail/overview/types.ts +2 -0
  836. package/src/plugins/builtin/ticker-detail/overview-return-coverage.test.tsx +71 -0
  837. package/src/plugins/builtin/ticker-detail/overview-tab.tsx +92 -80
  838. package/src/plugins/builtin/ticker-detail/pane.tsx +42 -19
  839. package/src/plugins/builtin/ticker-detail/quote-footer.ts +28 -0
  840. package/src/plugins/builtin/ticker-detail/quote-monitor/card.tsx +18 -9
  841. package/src/plugins/builtin/ticker-detail/quote-monitor/index.test.tsx +21 -29
  842. package/src/plugins/builtin/ticker-detail/quote-monitor/retained-status.test.tsx +134 -0
  843. package/src/plugins/builtin/ticker-detail/quote-status.test.tsx +116 -0
  844. package/src/plugins/builtin/ticker-detail/quote-time-integrity.test.ts +42 -0
  845. package/src/plugins/builtin/ticker-research-plugin.ts +8 -0
  846. package/src/plugins/builtin/treasury-auctions/cache.test.ts +43 -1
  847. package/src/plugins/builtin/treasury-auctions/cache.ts +29 -67
  848. package/src/plugins/builtin/treasury-auctions/client.test.ts +26 -8
  849. package/src/plugins/builtin/treasury-auctions/client.ts +28 -4
  850. package/src/plugins/builtin/treasury-auctions/headless.ts +2 -0
  851. package/src/plugins/builtin/treasury-auctions/model.test.ts +22 -0
  852. package/src/plugins/builtin/treasury-auctions/model.ts +28 -25
  853. package/src/plugins/builtin/treasury-auctions/pane.test.tsx +7 -22
  854. package/src/plugins/builtin/treasury-auctions/pane.tsx +32 -37
  855. package/src/plugins/builtin/treasury-auctions/types.ts +2 -2
  856. package/src/plugins/builtin/volatility/index.tsx +18 -47
  857. package/src/plugins/builtin/world-indices/headless.ts +4 -3
  858. package/src/plugins/builtin/world-indices/index.tsx +12 -5
  859. package/src/plugins/builtin/world-indices/pane.test.tsx +55 -15
  860. package/src/plugins/builtin/world-indices/table.tsx +3 -3
  861. package/src/plugins/builtin/world-venue-map/map.desktop.test.tsx +12 -73
  862. package/src/plugins/builtin/world-venue-map/pane.tsx +5 -7
  863. package/src/plugins/builtin/yield-curve/chart.test.ts +32 -0
  864. package/src/plugins/builtin/yield-curve/chart.ts +37 -0
  865. package/src/plugins/builtin/yield-curve/headless.test.ts +23 -7
  866. package/src/plugins/builtin/yield-curve/headless.ts +24 -7
  867. package/src/plugins/builtin/yield-curve/history.test.ts +124 -0
  868. package/src/plugins/builtin/yield-curve/history.ts +89 -0
  869. package/src/plugins/builtin/yield-curve/index.tsx +112 -97
  870. package/src/plugins/builtin/yield-curve/pane.test.tsx +137 -0
  871. package/src/plugins/builtin/yield-curve/treasury-data.test.ts +15 -5
  872. package/src/plugins/builtin/yield-curve/treasury-data.ts +25 -17
  873. package/src/plugins/bundle.test.ts +44 -1
  874. package/src/plugins/bundle.ts +59 -7
  875. package/src/plugins/catalog-backend.test.ts +1 -1
  876. package/src/plugins/catalog-backend.ts +0 -2
  877. package/src/plugins/catalog-browser.test.ts +9 -3
  878. package/src/plugins/catalog-browser.ts +37 -2
  879. package/src/plugins/catalog-manifest.ts +1 -3
  880. package/src/plugins/catalog-ui.ts +2 -6
  881. package/src/plugins/current-target.ts +17 -0
  882. package/src/plugins/external-runtime.ts +70 -0
  883. package/src/plugins/health.ts +21 -0
  884. package/src/plugins/host-contract.ts +26 -0
  885. package/src/plugins/host-link.test.ts +133 -0
  886. package/src/plugins/host-link.ts +49 -10
  887. package/src/plugins/host-module-imports.test.ts +94 -0
  888. package/src/plugins/host-module-imports.ts +73 -0
  889. package/src/plugins/host-modules.ts +2 -51
  890. package/src/plugins/host-resolver.test.ts +96 -0
  891. package/src/plugins/host-resolver.ts +102 -0
  892. package/src/plugins/host-smoke.ts +103 -0
  893. package/src/plugins/launch-layout.test.ts +131 -0
  894. package/src/plugins/launch-layout.ts +148 -0
  895. package/src/plugins/loader.test.ts +54 -0
  896. package/src/plugins/loader.ts +138 -36
  897. package/src/plugins/manager-node.ts +41 -0
  898. package/src/plugins/ownership.ts +4 -3
  899. package/src/plugins/pane-manager/dock-tree.ts +4 -2
  900. package/src/plugins/pane-manager/layout-state.ts +11 -4
  901. package/src/plugins/pane-manager/queries.ts +5 -4
  902. package/src/plugins/pane-manager.test.ts +22 -0
  903. package/src/plugins/pane-state.ts +48 -0
  904. package/src/plugins/plugin-names.ts +32 -0
  905. package/src/plugins/registry/contributions.ts +65 -126
  906. package/src/plugins/registry/index.test.ts +71 -5
  907. package/src/plugins/registry/index.ts +181 -102
  908. package/src/plugins/registry/pane-settings.ts +20 -14
  909. package/src/plugins/registry/plugin-state.ts +5 -20
  910. package/src/plugins/registry/setup-command.test.ts +62 -0
  911. package/src/plugins/registry/setup-command.ts +93 -0
  912. package/src/plugins/registry/shared.ts +1 -3
  913. package/src/plugins/registry/slots.ts +1 -1
  914. package/src/plugins/runtime/context.tsx +1 -0
  915. package/src/plugins/runtime/index.tsx +15 -49
  916. package/src/plugins/runtime/state.ts +28 -47
  917. package/src/plugins/seed.test.ts +57 -4
  918. package/src/plugins/seed.ts +28 -9
  919. package/src/plugins/team-state.ts +70 -0
  920. package/src/plugins/ticker-navigation.ts +5 -0
  921. package/src/plugins/web-bundled.ts +42 -0
  922. package/src/public/i18n.ts +17 -0
  923. package/src/public/layout.ts +12 -0
  924. package/src/public/market-data.ts +19 -0
  925. package/src/public/pane-hooks.ts +8 -1
  926. package/src/public/public-api.test.ts +39 -282
  927. package/src/public/quotes.ts +50 -0
  928. package/src/public/react.ts +44 -0
  929. package/src/public/remote.ts +23 -0
  930. package/src/public/test-support.ts +46 -1
  931. package/src/public/tickers.ts +40 -0
  932. package/src/public/time-series.ts +5 -0
  933. package/src/public/utils.ts +38 -2
  934. package/src/react/async-resource.test.tsx +106 -0
  935. package/src/react/async-resource.ts +65 -0
  936. package/src/react/plugins/plugin-slot.tsx +2 -10
  937. package/src/react/use-throttled-commit-value.ts +18 -1
  938. package/src/remote/app-host.tsx +17 -2
  939. package/src/remote/controller.test.ts +109 -3
  940. package/src/remote/controller.ts +44 -2
  941. package/src/remote/schema.ts +15 -0
  942. package/src/remote/semantic-tree.tsx +15 -7
  943. package/src/renderers/browser/app-services.ts +19 -52
  944. package/src/renderers/browser/bundled-plugins.test.ts +41 -0
  945. package/src/renderers/browser/bundled-plugins.ts +60 -0
  946. package/src/renderers/browser/cloud-transport.ts +8 -2
  947. package/src/renderers/browser/config-host.test.ts +70 -0
  948. package/src/renderers/browser/config-host.ts +75 -11
  949. package/src/renderers/browser/deeplink-bridge.test.ts +8 -4
  950. package/src/renderers/browser/deeplink-bridge.ts +18 -0
  951. package/src/renderers/browser/http-proxy-transport.test.ts +98 -0
  952. package/src/renderers/browser/http-proxy-transport.ts +83 -0
  953. package/src/renderers/browser/main.tsx +18 -2
  954. package/src/renderers/browser/research-entry.test.ts +24 -0
  955. package/src/renderers/browser/research-entry.ts +16 -2
  956. package/src/renderers/browser/storage.test.ts +7 -7
  957. package/src/renderers/cloudflare/http-proxy.test.ts +122 -0
  958. package/src/renderers/cloudflare/http-proxy.ts +197 -0
  959. package/src/renderers/cloudflare/worker.ts +7 -0
  960. package/src/renderers/electrobun/bun/core-capabilities.ts +0 -160
  961. package/src/renderers/electrobun/bun/desktop/host-requests.ts +4 -0
  962. package/src/renderers/electrobun/bun/external-plugins.ts +178 -63
  963. package/src/renderers/electrobun/bun/index.ts +49 -9
  964. package/src/renderers/electrobun/shared/protocol.ts +40 -4
  965. package/src/renderers/electrobun/view/app-services.ts +36 -90
  966. package/src/renderers/electrobun/view/backend-rpc.ts +12 -2
  967. package/src/renderers/electrobun/view/build-assets.ts +0 -1
  968. package/src/renderers/electrobun/view/capability-stream-client.ts +51 -0
  969. package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +232 -416
  970. package/src/renderers/electrobun/view/cli-pane-shot-frame.test.tsx +67 -0
  971. package/src/renderers/electrobun/view/cli-pane-shot-frame.tsx +39 -0
  972. package/src/renderers/electrobun/view/data-table/dom.ts +3 -0
  973. package/src/renderers/electrobun/view/data-table/frozen-column.test.tsx +73 -0
  974. package/src/renderers/electrobun/view/data-table/frozen-column.ts +22 -0
  975. package/src/renderers/electrobun/view/data-table/horizontal-navigation.test.tsx +77 -0
  976. package/src/renderers/electrobun/view/data-table/index.test.tsx +125 -0
  977. package/src/renderers/electrobun/view/data-table/index.tsx +48 -6
  978. package/src/renderers/electrobun/view/data-table/row.tsx +32 -3
  979. package/src/renderers/electrobun/view/desktop/control-styles.ts +7 -0
  980. package/src/renderers/electrobun/view/desktop/controls.test.tsx +141 -48
  981. package/src/renderers/electrobun/view/desktop/controls.tsx +86 -39
  982. package/src/renderers/electrobun/view/desktop/list-view.tsx +44 -9
  983. package/src/renderers/electrobun/view/dom-ui-host.tsx +4 -2
  984. package/src/renderers/electrobun/view/external-plugins.test.ts +13 -1
  985. package/src/renderers/electrobun/view/external-plugins.ts +47 -35
  986. package/src/renderers/electrobun/view/host/block-glyph-canvas.tsx +115 -0
  987. package/src/renderers/electrobun/view/host/box.test.tsx +50 -89
  988. package/src/renderers/electrobun/view/host/input.tsx +7 -1
  989. package/src/renderers/electrobun/view/host/media-surface.tsx +1 -2
  990. package/src/renderers/electrobun/view/host/scroll-box.desktop.test.tsx +26 -0
  991. package/src/renderers/electrobun/view/host/scroll-box.tsx +14 -6
  992. package/src/renderers/electrobun/view/host/text.tsx +28 -0
  993. package/src/renderers/electrobun/view/http-fetch.ts +3 -14
  994. package/src/renderers/electrobun/view/input-host.test.tsx +11 -47
  995. package/src/renderers/electrobun/view/input-host.tsx +1 -1
  996. package/src/renderers/electrobun/view/main.tsx +38 -6
  997. package/src/renderers/electrobun/view/native-stubs/native-stubs.test.ts +2 -7
  998. package/src/renderers/electrobun/view/remote/asset-data-client.ts +2 -0
  999. package/src/renderers/electrobun/view/remote/persistence.ts +2 -2
  1000. package/src/renderers/electrobun/view/remote/quote-subscription-registry.ts +6 -1
  1001. package/src/renderers/electrobun/view/rpc-codec.test.ts +64 -0
  1002. package/src/renderers/electrobun/view/rpc-codec.ts +35 -0
  1003. package/src/renderers/electrobun/view/screenshot-watermark.test.ts +48 -0
  1004. package/src/renderers/electrobun/view/screenshot-watermark.ts +105 -0
  1005. package/src/renderers/electrobun/view/styles.css +16 -0
  1006. package/src/renderers/electrobun/view/test-utils.tsx +76 -0
  1007. package/src/renderers/electrobun/view/toast-host.test.tsx +8 -25
  1008. package/src/renderers/electrobun/view/ui-host.tsx +0 -3
  1009. package/src/renderers/electrobun/view/window-fullscreen.ts +57 -0
  1010. package/src/renderers/opentui/interaction-performance.ts +29 -3
  1011. package/src/renderers/opentui/scrollbox-layout.ts +35 -0
  1012. package/src/renderers/opentui/start.tsx +7 -40
  1013. package/src/renderers/opentui/test-utils.tsx +117 -6
  1014. package/src/renderers/opentui/ui-host.tsx +1 -1
  1015. package/src/renderers/share/chart.test.ts +52 -0
  1016. package/src/renderers/share/chart.ts +74 -0
  1017. package/src/renderers/share/main.tsx +10 -2
  1018. package/src/renderers/share/styles.css +29 -0
  1019. package/src/renderers/share/view.test.tsx +20 -0
  1020. package/src/renderers/share/view.tsx +24 -15
  1021. package/src/shares/api.test.ts +15 -0
  1022. package/src/shares/live.ts +27 -0
  1023. package/src/shares/pane.ts +3 -0
  1024. package/src/shares/payload.ts +35 -3
  1025. package/src/sources/gloomberb-cloud/history-coverage.test.ts +119 -0
  1026. package/src/sources/gloomberb-cloud/index.test.ts +307 -20
  1027. package/src/sources/gloomberb-cloud/index.ts +176 -62
  1028. package/src/sources/gloomberb-cloud/news.ts +11 -3
  1029. package/src/sources/gloomberb-cloud/normalizers.test.ts +27 -1
  1030. package/src/sources/gloomberb-cloud/normalizers.ts +29 -8
  1031. package/src/sources/gloomberb-cloud/quote-metadata.test.ts +50 -0
  1032. package/src/sources/gloomberb-cloud/valuation-observations.ts +29 -0
  1033. package/src/sources/history-coverage.test.ts +40 -0
  1034. package/src/sources/history-coverage.ts +97 -0
  1035. package/src/sources/listing-history.ts +52 -0
  1036. package/src/sources/listing-target.ts +41 -0
  1037. package/src/sources/provider-router/arca-cache.test.ts +97 -0
  1038. package/src/sources/provider-router/batches.ts +21 -5
  1039. package/src/sources/provider-router/broker-session.test.ts +52 -0
  1040. package/src/sources/provider-router/brokers.ts +1 -0
  1041. package/src/sources/provider-router/cache.test.ts +133 -0
  1042. package/src/sources/provider-router/cache.ts +113 -8
  1043. package/src/sources/provider-router/cached-financials.test.ts +104 -14
  1044. package/src/sources/provider-router/cached-routes.test.ts +212 -0
  1045. package/src/sources/provider-router/cached-routes.ts +223 -0
  1046. package/src/sources/provider-router/connection-health.ts +1 -0
  1047. package/src/sources/provider-router/financial-routes.ts +90 -26
  1048. package/src/sources/provider-router/financials.test.ts +97 -1
  1049. package/src/sources/provider-router/financials.ts +217 -44
  1050. package/src/sources/provider-router/fixtures/quarterly-source-disagreements.json +438 -0
  1051. package/src/sources/provider-router/history-boundary-cache.test.ts +72 -0
  1052. package/src/sources/provider-router/history-gap-cache.test.ts +84 -0
  1053. package/src/sources/provider-router/history-gaps.test.ts +141 -0
  1054. package/src/sources/provider-router/history.test.ts +124 -3
  1055. package/src/sources/provider-router/history.ts +156 -46
  1056. package/src/sources/provider-router/index.test.ts +19 -13
  1057. package/src/sources/provider-router/index.ts +83 -18
  1058. package/src/sources/provider-router/listing-history.test.ts +139 -0
  1059. package/src/sources/provider-router/listing-identity.test.ts +128 -0
  1060. package/src/sources/provider-router/non-company-metadata.test.ts +95 -0
  1061. package/src/sources/provider-router/o-income-basis.test.ts +64 -0
  1062. package/src/sources/provider-router/primary.ts +44 -8
  1063. package/src/sources/provider-router/profile-enrichment.test.ts +171 -0
  1064. package/src/sources/provider-router/quote-completion.test.ts +62 -0
  1065. package/src/sources/provider-router/quote-domain.test.ts +92 -0
  1066. package/src/sources/provider-router/routing.ts +2 -30
  1067. package/src/sources/provider-router/search.ts +2 -11
  1068. package/src/sources/provider-router/shell-history-cache.test.ts +131 -0
  1069. package/src/sources/provider-router/statement-history.test.ts +71 -0
  1070. package/src/sources/provider-router/statement-history.ts +15 -0
  1071. package/src/sources/provider-router/statement-observations.test.ts +126 -0
  1072. package/src/sources/provider-router/streaming.ts +1 -1
  1073. package/src/sources/provider-router/supplemental.ts +2 -389
  1074. package/src/sources/provider-router/valuation-retractions.test.ts +280 -0
  1075. package/src/sources/sec-edgar-shares.fixture.json +188 -0
  1076. package/src/sources/sec-edgar-shares.test.ts +66 -0
  1077. package/src/sources/sec-edgar.test.ts +146 -0
  1078. package/src/sources/sec-edgar.ts +136 -37
  1079. package/src/sources/sec-income-attribution.test.ts +93 -0
  1080. package/src/sources/yahoo-finance/financials.ts +23 -23
  1081. package/src/sources/yahoo-finance/mappers.test.ts +95 -1
  1082. package/src/sources/yahoo-finance/mappers.ts +104 -43
  1083. package/src/sources/yahoo-finance/options.test.ts +13 -0
  1084. package/src/sources/yahoo-finance/options.ts +4 -2
  1085. package/src/sources/yahoo-finance/quote-summary.ts +25 -12
  1086. package/src/sources/yahoo-finance/requests.test.ts +37 -0
  1087. package/src/sources/yahoo-finance/requests.ts +9 -2
  1088. package/src/sources/yahoo-finance/snapshots.test.ts +140 -0
  1089. package/src/sources/yahoo-finance/snapshots.ts +21 -11
  1090. package/src/sources/yahoo-finance/symbols.test.ts +8 -0
  1091. package/src/sources/yahoo-finance/symbols.ts +60 -11
  1092. package/src/sources/yahoo-finance/types.ts +8 -0
  1093. package/src/sources/yahoo-finance/yahoo-chart-interval.ts +18 -0
  1094. package/src/sources/yahoo-finance.test.ts +20 -0
  1095. package/src/sources/yahoo-finance.ts +54 -20
  1096. package/src/state/app/bootstrap.test.ts +124 -0
  1097. package/src/state/app/bootstrap.ts +106 -130
  1098. package/src/state/app/context/index.test.tsx +56 -0
  1099. package/src/state/app/context/index.tsx +101 -31
  1100. package/src/state/app/context/selector.test.tsx +38 -2
  1101. package/src/state/config-save-scheduler.ts +16 -4
  1102. package/src/state/hooks/inline-ticker-failures.test.ts +77 -0
  1103. package/src/state/hooks/inline-ticker-failures.ts +100 -0
  1104. package/src/state/hooks/inline-tickers.test.tsx +47 -11
  1105. package/src/state/hooks/inline-tickers.ts +254 -85
  1106. package/src/state/hooks/quote-streaming.ts +6 -13
  1107. package/src/state/hooks/session-snapshot.ts +9 -5
  1108. package/src/state/persist-scheduler.test.ts +54 -1
  1109. package/src/state/persist-scheduler.ts +36 -3
  1110. package/src/state/session-persistence.test.ts +46 -0
  1111. package/src/sync/core-contributors.test.ts +35 -6
  1112. package/src/sync/core-contributors.ts +30 -27
  1113. package/src/test-support/market-session.ts +12 -0
  1114. package/src/test-support/pane.tsx +52 -0
  1115. package/src/test-support/plugin-runtime.ts +5 -0
  1116. package/src/theme/color-utils.ts +90 -33
  1117. package/src/tickers/instrument-label.ts +10 -0
  1118. package/src/tickers/list.test.ts +1 -0
  1119. package/src/tickers/list.ts +1 -1
  1120. package/src/tickers/metadata.ts +4 -1
  1121. package/src/tickers/open-target.test.ts +86 -0
  1122. package/src/tickers/open-target.ts +48 -9
  1123. package/src/tickers/search/identity.ts +19 -0
  1124. package/src/tickers/search/index.test.ts +263 -8
  1125. package/src/tickers/search/index.ts +164 -29
  1126. package/src/tickers/search/ranking.ts +85 -9
  1127. package/src/tickers/search/types.ts +5 -1
  1128. package/src/tickers/search/upsert.ts +14 -6
  1129. package/src/tickers/search-contract-context.test.tsx +161 -0
  1130. package/src/tickers/search-contract-templates.test.ts +83 -0
  1131. package/src/tickers/selection.ts +21 -0
  1132. package/src/time-series/alignment.ts +11 -3
  1133. package/src/time-series/bond-price-history.test.ts +52 -0
  1134. package/src/time-series/chart-data.test.ts +44 -12
  1135. package/src/time-series/chart-data.ts +36 -8
  1136. package/src/time-series/economic.test.ts +44 -0
  1137. package/src/time-series/economic.ts +42 -0
  1138. package/src/time-series/field-catalog.ts +3 -2
  1139. package/src/time-series/financial-history-request.test.ts +20 -0
  1140. package/src/time-series/financial-period-coverage.test.ts +37 -0
  1141. package/src/time-series/financial-period-coverage.ts +59 -0
  1142. package/src/time-series/financial-period-gaps.test.ts +128 -0
  1143. package/src/time-series/fixtures/q4-reported-common-income.json +394 -0
  1144. package/src/time-series/fixtures/q4-reported-per-share.json +305 -0
  1145. package/src/time-series/forward-valuation.test.ts +131 -0
  1146. package/src/time-series/forward-valuation.ts +247 -0
  1147. package/src/time-series/fundamentals.test.ts +111 -24
  1148. package/src/time-series/fundamentals.ts +260 -131
  1149. package/src/time-series/hooks.ts +7 -3
  1150. package/src/time-series/legacy-contract-live.test.ts +23 -0
  1151. package/src/time-series/live-quotes.test.ts +5 -2
  1152. package/src/time-series/live-quotes.ts +23 -29
  1153. package/src/time-series/market-price-units.test.ts +75 -0
  1154. package/src/time-series/market.ts +55 -15
  1155. package/src/time-series/price-comparison.test.ts +233 -0
  1156. package/src/time-series/price-comparison.ts +133 -0
  1157. package/src/time-series/price-history-integrity-window.test.ts +137 -0
  1158. package/src/time-series/price-history-integrity.test.ts +195 -0
  1159. package/src/time-series/q4-common-income.test.ts +63 -0
  1160. package/src/time-series/q4-per-share.test.ts +144 -0
  1161. package/src/time-series/reporting-currency.test.ts +99 -0
  1162. package/src/time-series/reporting-currency.ts +37 -0
  1163. package/src/time-series/reporting.ts +38 -2
  1164. package/src/time-series/resolve.test.ts +528 -366
  1165. package/src/time-series/resolve.ts +322 -76
  1166. package/src/time-series/sec-eps-research.test.ts +55 -0
  1167. package/src/time-series/session-history-domain.test.ts +160 -0
  1168. package/src/{cli/pane-functions/intraday-shot.ts → time-series/session-history.ts} +96 -42
  1169. package/src/time-series/spec-studies.test.ts +177 -6
  1170. package/src/time-series/studies.ts +173 -38
  1171. package/src/time-series/transforms.test.ts +38 -2
  1172. package/src/time-series/transforms.ts +5 -1
  1173. package/src/time-series/types.ts +30 -0
  1174. package/src/time-series/use-chart-resolution.test.tsx +72 -4
  1175. package/src/time-series/use-chart-resolution.ts +45 -28
  1176. package/src/time-series/valuation-currency.test.ts +127 -0
  1177. package/src/time-series/valuation-currency.ts +46 -0
  1178. package/src/time-series/valuation-denominator.test.ts +240 -0
  1179. package/src/time-series/valuation-live-status.test.ts +63 -0
  1180. package/src/time-series/valuation-price.test.ts +264 -0
  1181. package/src/time-series/valuation-price.ts +68 -0
  1182. package/src/types/broker.ts +2 -1
  1183. package/src/types/config.test.ts +31 -0
  1184. package/src/types/config.ts +49 -10
  1185. package/src/types/data-provider.ts +43 -0
  1186. package/src/types/exchange-rate.ts +13 -0
  1187. package/src/types/financials.ts +164 -2
  1188. package/src/types/headless.ts +23 -0
  1189. package/src/types/instrument.ts +11 -0
  1190. package/src/types/plugin.ts +108 -2
  1191. package/src/types/ticker.ts +10 -2
  1192. package/src/ui/context-menu.test.ts +2 -1
  1193. package/src/ui/context-menu.tsx +3 -3
  1194. package/src/ui/host.tsx +6 -2
  1195. package/src/ui/index.tsx +3 -4
  1196. package/src/updater.test.ts +17 -1
  1197. package/src/updater.ts +4 -2
  1198. package/src/utils/dom-screenshot.test.ts +52 -0
  1199. package/src/utils/dom-screenshot.ts +70 -15
  1200. package/src/utils/exchange-rate-snapshot.test.ts +22 -0
  1201. package/src/utils/exchange-rate-snapshot.ts +62 -0
  1202. package/src/utils/exchanges.test.ts +24 -0
  1203. package/src/utils/exchanges.ts +22 -11
  1204. package/src/utils/financial-statements.test.ts +74 -1
  1205. package/src/utils/financial-statements.ts +119 -14
  1206. package/src/utils/format.test.ts +21 -1
  1207. package/src/utils/format.ts +56 -23
  1208. package/src/utils/fundamentals.ts +15 -0
  1209. package/src/utils/fx-status.test.ts +16 -0
  1210. package/src/utils/fx-status.ts +46 -0
  1211. package/src/utils/http-proxy-response.ts +44 -0
  1212. package/src/utils/http-transport.ts +21 -1
  1213. package/src/utils/income-statement.ts +46 -0
  1214. package/src/utils/instrument-identity.test.ts +26 -0
  1215. package/src/utils/instrument-identity.ts +35 -0
  1216. package/src/utils/latest-financial-period.test.ts +19 -0
  1217. package/src/utils/latest-financial-period.ts +26 -0
  1218. package/src/utils/market-capitalization-consumers.test.ts +59 -0
  1219. package/src/utils/market-capitalization.test.ts +38 -0
  1220. package/src/utils/market-capitalization.ts +58 -0
  1221. package/src/utils/options.test.ts +20 -0
  1222. package/src/utils/options.ts +4 -4
  1223. package/src/utils/perf-marks.ts +26 -0
  1224. package/src/utils/plugin-proxy-hosts.json +16 -0
  1225. package/src/utils/plugin-proxy-hosts.ts +25 -0
  1226. package/src/utils/price-earnings.test.ts +39 -0
  1227. package/src/utils/price-earnings.ts +13 -0
  1228. package/src/utils/price-history-integrity.ts +61 -0
  1229. package/src/utils/price-history.test.ts +41 -3
  1230. package/src/utils/price-history.ts +90 -6
  1231. package/src/utils/reported-money.test.ts +25 -0
  1232. package/src/utils/reported-money.ts +31 -0
  1233. package/src/utils/screenshot-watermark.ts +27 -0
  1234. package/src/utils/sec-eps-basis.test.ts +82 -0
  1235. package/src/utils/sec-eps-basis.ts +152 -0
  1236. package/src/utils/sec.test.ts +12 -10
  1237. package/src/utils/sec.ts +4 -3
  1238. package/src/utils/semver.test.ts +31 -0
  1239. package/src/utils/semver.ts +48 -0
  1240. package/src/utils/sort-values.test.ts +11 -0
  1241. package/src/utils/sort-values.ts +2 -0
  1242. package/src/utils/statement-observations.ts +121 -0
  1243. package/src/cli/commands/automation.test.ts +0 -211
  1244. package/src/components/chart/native/surface/sync.ts +0 -34
  1245. package/src/components/command-bar/panel/body.tsx +0 -301
  1246. package/src/components/onboarding/account-step/chooser-panel.tsx +0 -51
  1247. package/src/plugins/builtin/ai/agent-history.ts +0 -143
  1248. package/src/plugins/builtin/ai/ask-ai-detail-tab.tsx +0 -466
  1249. package/src/plugins/builtin/ai/ask-ai.test.tsx +0 -365
  1250. package/src/plugins/builtin/ai/index.test.ts +0 -302
  1251. package/src/plugins/builtin/ai/index.tsx +0 -440
  1252. package/src/plugins/builtin/ai/pane-settings.test.ts +0 -155
  1253. package/src/plugins/builtin/ai/pane-settings.ts +0 -319
  1254. package/src/plugins/builtin/ai/pi/credential-store.test.ts +0 -80
  1255. package/src/plugins/builtin/ai/pi/credential-store.ts +0 -138
  1256. package/src/plugins/builtin/ai/pi/file-store.ts +0 -138
  1257. package/src/plugins/builtin/ai/pi/host.test.ts +0 -500
  1258. package/src/plugins/builtin/ai/pi/host.ts +0 -565
  1259. package/src/plugins/builtin/ai/pi/index.ts +0 -5
  1260. package/src/plugins/builtin/ai/pi/models-store.test.ts +0 -44
  1261. package/src/plugins/builtin/ai/pi/models-store.ts +0 -141
  1262. package/src/plugins/builtin/ai/pi/providers.ts +0 -68
  1263. package/src/plugins/builtin/ai/pi/runtime.test.ts +0 -240
  1264. package/src/plugins/builtin/ai/pi/runtime.ts +0 -636
  1265. package/src/plugins/builtin/ai/providers.test.ts +0 -68
  1266. package/src/plugins/builtin/ai/providers.ts +0 -191
  1267. package/src/plugins/builtin/ai/runner-selection.test.ts +0 -174
  1268. package/src/plugins/builtin/ai/runner-selection.ts +0 -193
  1269. package/src/plugins/builtin/ai/runner-selector.tsx +0 -153
  1270. package/src/plugins/builtin/ai/runner.test.ts +0 -198
  1271. package/src/plugins/builtin/ai/runner.ts +0 -316
  1272. package/src/plugins/builtin/ai/screener/contract.test.ts +0 -70
  1273. package/src/plugins/builtin/ai/screener/contract.ts +0 -136
  1274. package/src/plugins/builtin/ai/screener/editor-runtime.ts +0 -160
  1275. package/src/plugins/builtin/ai/screener/editor.tsx +0 -131
  1276. package/src/plugins/builtin/ai/screener/footer.ts +0 -104
  1277. package/src/plugins/builtin/ai/screener/keyboard.ts +0 -106
  1278. package/src/plugins/builtin/ai/screener/market-runtime.ts +0 -101
  1279. package/src/plugins/builtin/ai/screener/model.test.ts +0 -24
  1280. package/src/plugins/builtin/ai/screener/model.ts +0 -113
  1281. package/src/plugins/builtin/ai/screener/pane.test.tsx +0 -479
  1282. package/src/plugins/builtin/ai/screener/pane.tsx +0 -438
  1283. package/src/plugins/builtin/ai/screener/results-view.tsx +0 -144
  1284. package/src/plugins/builtin/ai/screener/results.ts +0 -139
  1285. package/src/plugins/builtin/ai/screener/runner.ts +0 -164
  1286. package/src/plugins/builtin/ai/screener/tabs-bar.tsx +0 -65
  1287. package/src/plugins/builtin/ai/settings.ts +0 -81
  1288. package/src/plugins/builtin/ai/ticker-context.ts +0 -65
  1289. package/src/plugins/builtin/ai/use-runtime-providers.ts +0 -28
  1290. package/src/plugins/builtin/ai/workspace/model.test.ts +0 -227
  1291. package/src/plugins/builtin/ai/workspace/model.ts +0 -283
  1292. package/src/plugins/builtin/ai/workspace/pane.test.tsx +0 -197
  1293. package/src/plugins/builtin/ai/workspace/pane.tsx +0 -907
  1294. package/src/plugins/builtin/chat/message/action-chip.tsx +0 -39
  1295. package/src/plugins/builtin/cloud/askg/verify.ts +0 -130
  1296. package/src/plugins/builtin/earnings/data/data.test.ts +0 -90
  1297. package/src/plugins/builtin/earnings/data/data.ts +0 -115
  1298. package/src/plugins/builtin/fear-greed/cache.test.ts +0 -90
  1299. package/src/plugins/builtin/fear-greed/cache.ts +0 -154
  1300. package/src/plugins/builtin/fear-greed/charts.tsx +0 -305
  1301. package/src/plugins/builtin/fear-greed/data.test.ts +0 -72
  1302. package/src/plugins/builtin/fear-greed/data.ts +0 -375
  1303. package/src/plugins/builtin/fear-greed/format.ts +0 -87
  1304. package/src/plugins/builtin/fear-greed/headless.test.ts +0 -53
  1305. package/src/plugins/builtin/fear-greed/headless.ts +0 -84
  1306. package/src/plugins/builtin/fear-greed/index.tsx +0 -43
  1307. package/src/plugins/builtin/fear-greed/pane.tsx +0 -169
  1308. package/src/plugins/builtin/ipo-calendar/cache.ts +0 -101
  1309. package/src/plugins/builtin/ipo-calendar/client.test.ts +0 -31
  1310. package/src/plugins/builtin/ipo-calendar/client.ts +0 -311
  1311. package/src/plugins/builtin/ipo-calendar/headless.test.ts +0 -89
  1312. package/src/plugins/builtin/ipo-calendar/headless.ts +0 -127
  1313. package/src/plugins/builtin/ipo-calendar/index.tsx +0 -68
  1314. package/src/plugins/builtin/ipo-calendar/model.ts +0 -133
  1315. package/src/plugins/builtin/ipo-calendar/pane.tsx +0 -328
  1316. package/src/plugins/builtin/ipo-calendar/types.ts +0 -19
  1317. package/src/plugins/builtin/market-halts/client.ts +0 -114
  1318. package/src/plugins/builtin/market-halts/index.tsx +0 -30
  1319. package/src/plugins/builtin/market-halts/model.test.ts +0 -187
  1320. package/src/plugins/builtin/market-halts/model.ts +0 -291
  1321. package/src/plugins/builtin/market-halts/pane.tsx +0 -256
  1322. package/src/plugins/builtin/market-heatmap/data.test.ts +0 -122
  1323. package/src/plugins/builtin/market-heatmap/data.ts +0 -305
  1324. package/src/plugins/builtin/market-heatmap/index.tsx +0 -400
  1325. package/src/plugins/builtin/market-valuation/model.ts +0 -8
  1326. package/src/plugins/builtin/notes/sync.test.ts +0 -49
  1327. package/src/plugins/builtin/notes/sync.ts +0 -98
  1328. package/src/plugins/builtin/polls/client.ts +0 -57
  1329. package/src/plugins/builtin/polls/hooks.ts +0 -20
  1330. package/src/plugins/builtin/polls/index.tsx +0 -35
  1331. package/src/plugins/builtin/polls/normalize.test.ts +0 -230
  1332. package/src/plugins/builtin/polls/normalize.ts +0 -319
  1333. package/src/plugins/builtin/polls/pane.tsx +0 -722
  1334. package/src/plugins/builtin/polls/types.ts +0 -77
  1335. package/src/plugins/builtin/scanner/waiting.tsx +0 -11
  1336. package/src/plugins/builtin/shared/public-share.ts +0 -23
  1337. package/src/plugins/builtin/tv/channels.ts +0 -27
  1338. package/src/plugins/builtin/tv/index.tsx +0 -40
  1339. package/src/plugins/builtin/tv/pane.tsx +0 -346
  1340. package/src/plugins/builtin/tv/youtube-embed.test.ts +0 -84
  1341. package/src/plugins/builtin/tv/youtube-embed.ts +0 -173
  1342. package/src/plugins/builtin/tv/youtube-stream.ts +0 -125
  1343. package/src/plugins/catalog-manifest.test.ts +0 -58
  1344. package/src/plugins/prediction-markets/backend-plugin.ts +0 -21
  1345. package/src/plugins/prediction-markets/cache.ts +0 -163
  1346. package/src/plugins/prediction-markets/capability.test.ts +0 -281
  1347. package/src/plugins/prediction-markets/capability.ts +0 -171
  1348. package/src/plugins/prediction-markets/categories.ts +0 -213
  1349. package/src/plugins/prediction-markets/chart.tsx +0 -158
  1350. package/src/plugins/prediction-markets/cli.ts +0 -28
  1351. package/src/plugins/prediction-markets/columns.ts +0 -134
  1352. package/src/plugins/prediction-markets/controller/catalog.ts +0 -395
  1353. package/src/plugins/prediction-markets/controller/data.ts +0 -177
  1354. package/src/plugins/prediction-markets/controller/detail.ts +0 -247
  1355. package/src/plugins/prediction-markets/controller/effects.ts +0 -253
  1356. package/src/plugins/prediction-markets/controller/index.ts +0 -368
  1357. package/src/plugins/prediction-markets/controller/keyboard.ts +0 -245
  1358. package/src/plugins/prediction-markets/controller/live-updates.ts +0 -86
  1359. package/src/plugins/prediction-markets/controller/selection.ts +0 -59
  1360. package/src/plugins/prediction-markets/controller/status.ts +0 -104
  1361. package/src/plugins/prediction-markets/detail/book.tsx +0 -144
  1362. package/src/plugins/prediction-markets/detail/outcomes.tsx +0 -101
  1363. package/src/plugins/prediction-markets/detail/overview.tsx +0 -84
  1364. package/src/plugins/prediction-markets/detail/pane.tsx +0 -344
  1365. package/src/plugins/prediction-markets/detail/rules.tsx +0 -31
  1366. package/src/plugins/prediction-markets/detail/shared.tsx +0 -49
  1367. package/src/plugins/prediction-markets/detail/trades.tsx +0 -101
  1368. package/src/plugins/prediction-markets/detail.test.tsx +0 -94
  1369. package/src/plugins/prediction-markets/headless.test.ts +0 -119
  1370. package/src/plugins/prediction-markets/headless.ts +0 -255
  1371. package/src/plugins/prediction-markets/index.tsx +0 -117
  1372. package/src/plugins/prediction-markets/keyboard.ts +0 -65
  1373. package/src/plugins/prediction-markets/launch.test.ts +0 -126
  1374. package/src/plugins/prediction-markets/launch.ts +0 -275
  1375. package/src/plugins/prediction-markets/metrics.ts +0 -328
  1376. package/src/plugins/prediction-markets/navigation.ts +0 -77
  1377. package/src/plugins/prediction-markets/outcome-order.ts +0 -19
  1378. package/src/plugins/prediction-markets/pane.test.tsx +0 -562
  1379. package/src/plugins/prediction-markets/pane.tsx +0 -347
  1380. package/src/plugins/prediction-markets/plugin.test.tsx +0 -645
  1381. package/src/plugins/prediction-markets/rows.ts +0 -229
  1382. package/src/plugins/prediction-markets/services/fetch.ts +0 -121
  1383. package/src/plugins/prediction-markets/services/kalshi/adapter.ts +0 -398
  1384. package/src/plugins/prediction-markets/services/kalshi/normalize.ts +0 -211
  1385. package/src/plugins/prediction-markets/services/kalshi/types.ts +0 -103
  1386. package/src/plugins/prediction-markets/services/polymarket/adapter.ts +0 -177
  1387. package/src/plugins/prediction-markets/services/polymarket/detail.ts +0 -356
  1388. package/src/plugins/prediction-markets/services/polymarket/normalize.ts +0 -239
  1389. package/src/plugins/prediction-markets/services/polymarket/types.ts +0 -66
  1390. package/src/plugins/prediction-markets/services/polymarket/ws.ts +0 -128
  1391. package/src/plugins/prediction-markets/settings.ts +0 -163
  1392. package/src/plugins/prediction-markets/test-helpers.tsx +0 -591
  1393. package/src/plugins/prediction-markets/types.ts +0 -179
  1394. package/src/plugins/registry/context.ts +0 -218
  1395. package/src/renderers/electrobun/bun/desktop/media.ts +0 -17
  1396. package/src/renderers/electrobun/view/ai-host.ts +0 -198
  1397. package/src/renderers/electrobun/view/native-stubs/chart/surface-sync.ts +0 -1
  1398. package/src/renderers/electrobun/view/resource-store.test.ts +0 -44
  1399. package/src/shares/chart-snapshot.test.ts +0 -34
  1400. package/src/shares/chart-snapshot.ts +0 -28
  1401. package/src/sources/provider-router/document-routes.ts +0 -203
  1402. package/src/types/media.ts +0 -19
@@ -5,8 +5,7 @@ import {
5
5
  useRef,
6
6
  useState,
7
7
  } from "react";
8
- import { CloudVerificationPanel } from "../../plugins/builtin/cloud/verification-panel";
9
- import { recordResearchActivity } from "../../api-client/research-activity";
8
+ import { recordResearchActivity, type ResearchActivity } from "../../api-client/research-activity";
10
9
  import { apiClient, type CloudPricing } from "../../api-client";
11
10
  import type { AppBrokerImportRuntime } from "../../app/runtime/broker-import";
12
11
  import type { SyncBrokerInstanceResult } from "../../brokers/sync-broker-instance";
@@ -15,6 +14,7 @@ import {
15
14
  type AppConfig,
16
15
  findPaneInstance,
17
16
  type OnboardingProgress,
17
+ type OnboardingStage,
18
18
  } from "../../types/config";
19
19
  import { resolveBrokerConfigFields, type BrokerConfigField } from "../../types/broker";
20
20
  import { useShortcut, useViewport } from "../../react/input";
@@ -24,18 +24,23 @@ import {
24
24
  useAppStateRef,
25
25
  } from "../../state/app/context";
26
26
  import { useAppActive } from "../../state/app/activity";
27
- import { Box, Text, TextAttributes, useUiHost, type InputRenderable } from "../../ui";
27
+ import { Box, Text, TextAttributes, useCommandBarShortcut, useUiHost, type InputRenderable } from "../../ui";
28
28
  import { useThemeColors } from "../../theme/theme-context";
29
29
  import { t, tf } from "../../i18n";
30
30
  import { useAppLanguage } from "../../i18n/react";
31
31
  import type { PluginRegistry } from "../../plugins/registry";
32
32
  import { chatController } from "../../plugins/builtin/chat/controller";
33
- import { formatCloudMonthlyPrice } from "../../plugins/builtin/account-management/model";
33
+ import {
34
+ type CloudBillingInterval,
35
+ formatCloudPrice,
36
+ monthsFreeYearly,
37
+ } from "../../plugins/builtin/account-management/model";
34
38
  import { useCloudUpgradeAction } from "../../plugins/builtin/shared/cloud-upgrade";
35
39
  import { usePlanAccess } from "../../plugins/builtin/shared/plan-access";
36
- import type { ListViewItem } from "../ui";
40
+ import { Button, SegmentedControl, type ListViewItem } from "../ui";
37
41
  import { AccountStep, PortfolioStep, type PortfolioSub } from "./onboarding-steps";
38
42
  import {
43
+ ONBOARDING_DESKTOP,
39
44
  OnboardingActions,
40
45
  OnboardingButton,
41
46
  OnboardingCoach,
@@ -45,39 +50,54 @@ import {
45
50
  OnboardingTitle,
46
51
  type OnboardingSectionId,
47
52
  } from "./onboarding-frame";
48
- import { ACCOUNT_CHOICE_IDS } from "../../plugins/builtin/cloud/auth-model";
49
53
  import { useOnboardingAccount } from "./wizard-account";
50
54
  import { useOnboardingBrokerSync } from "./wizard-broker-sync";
55
+ import { POSITION_FIELDS, useOnboardingPositions } from "./wizard-positions";
56
+ import { applyFirstRunLayout, buildFirstRunLayout, planFirstRunWatchlist } from "./first-run-workspace";
57
+ import { debugLog } from "../../utils/debug-log";
51
58
  import {
52
59
  getConnectableBrokerOptions,
53
60
  getOnboardingProgress,
61
+ pickLargestBrokerPosition,
62
+ pickLargestPosition,
54
63
  withOnboardingProgress,
55
64
  type BrokerOption,
56
65
  } from "./wizard-model";
57
66
 
67
+ const onboardingLog = debugLog.createLogger("onboarding");
68
+
58
69
  interface OnboardingWizardProps {
59
70
  pluginRegistry: PluginRegistry;
60
71
  importBrokerPositions: AppBrokerImportRuntime["importBrokerPositions"];
61
72
  onComplete: (config: AppConfig) => void | Promise<void>;
62
73
  }
63
74
 
75
+ /** One funnel milestone per stage the user reaches; the account step reports sign-in itself. */
76
+ const STAGE_ACTIVITY: Partial<Record<OnboardingStage, ResearchActivity>> = {
77
+ portfolio: "onboarding_started",
78
+ research: "onboarding_research_opened",
79
+ account: "onboarding_account_viewed",
80
+ upgrade: "onboarding_pro_viewed",
81
+ };
82
+
64
83
  export function OnboardingWizard({ pluginRegistry, importBrokerPositions, onComplete }: OnboardingWizardProps) {
65
84
  const language = useAppLanguage();
66
85
  const colors = useThemeColors();
67
86
  const desktop = useUiHost().kind === "desktop-web";
87
+ const commandBarShortcut = useCommandBarShortcut();
68
88
  const { height: viewportHeight } = useViewport();
69
89
  const dispatch = useAppDispatch();
70
90
  const stateRef = useAppStateRef();
71
91
  const config = useAppSelector((state) => state.config);
72
- const commandBarOpen = useAppSelector((state) => state.commandBarOpen);
73
92
  const progress = getOnboardingProgress(config);
74
93
  const stage = progress.stage;
75
94
  const [persistenceError, setPersistenceError] = useState<string | null>(null);
76
95
  const [isFinishing, setIsFinishing] = useState(false);
77
96
  const researchOpenedRef = useRef<string | null>(null);
78
97
  const [pricing, setPricing] = useState<CloudPricing | null>(null);
98
+ const [billingInterval, setBillingInterval] = useState<CloudBillingInterval>("month");
79
99
 
80
- const [portfolioSub, setPortfolioSub] = useState<PortfolioSub>("choose");
100
+ const [portfolioSub, setPortfolioSub] = useState<PortfolioSub>("positions");
81
101
  const [portfolioOptionIdx, setPortfolioOptionIdx] = useState(0);
82
102
  const [brokerValues, setBrokerValues] = useState<Record<string, Record<string, string>>>({});
83
103
  const [selectedBrokerId, setSelectedBrokerId] = useState<string | null>(null);
@@ -88,23 +108,18 @@ export function OnboardingWizard({ pluginRegistry, importBrokerPositions, onComp
88
108
  const progressSaveQueueRef = useRef<Promise<void>>(Promise.resolve());
89
109
  const finishingRef = useRef(false);
90
110
 
111
+ // Enter inside every form is handled once, by the shortcut below: the
112
+ // fields deliberately get no onSubmit, because the host input fires it in
113
+ // the same keystroke and the two paths used to submit twice.
91
114
  const brokerOptions = useMemo(
92
115
  (): BrokerOption[] => getConnectableBrokerOptions(pluginRegistry.brokers),
93
116
  [pluginRegistry.brokers],
94
117
  );
95
- const portfolioChoices = useMemo<ListViewItem[]>(() => [
96
- {
97
- id: "manual",
98
- label: t("Research a company"),
99
- description: t("Add one company with the command bar"),
100
- detail: t("Recommended"),
101
- },
102
- ...brokerOptions.map((broker) => ({
103
- id: broker.id,
104
- label: tf("Connect {broker}", { broker: broker.name }),
105
- description: tf("Import positions from {broker}", { broker: broker.name }),
106
- })),
107
- ], [brokerOptions, language]);
118
+ const brokerChoices = useMemo<ListViewItem[]>(() => brokerOptions.map((broker) => ({
119
+ id: broker.id,
120
+ label: tf("Connect {broker}", { broker: broker.name }),
121
+ description: tf("Import positions from {broker}", { broker: broker.name }),
122
+ })), [brokerOptions, language]);
108
123
  const activeBrokerFields = useMemo((): BrokerConfigField[] => {
109
124
  if (!selectedBrokerId) return [];
110
125
  const broker = brokerOptions.find((option) => option.id === selectedBrokerId);
@@ -149,37 +164,137 @@ export function OnboardingWizard({ pluginRegistry, importBrokerPositions, onComp
149
164
  void persistProgress(patch, baseConfig).catch(() => {});
150
165
  }, [persistProgress]);
151
166
 
167
+ // Pro follows sign-in directly. Email verification continues in the status
168
+ // bar, so an unread inbox never stalls the first session.
152
169
  const account = useOnboardingAccount({
153
170
  nextStep: () => {
154
- saveProgressInBackground({ stage: apiClient.getCurrentUser()?.emailVerified ? "upgrade" : "verify", accountStatus: "signed-in" });
171
+ recordResearchActivity("onboarding_signed_in");
172
+ saveProgressInBackground({ stage: "upgrade", accountStatus: "signed-in" });
155
173
  },
156
174
  setEditingField,
157
175
  });
158
176
 
177
+ const positions = useOnboardingPositions({ pluginRegistry, onFieldEditing: setEditingField });
178
+ const positionCount = positions.positions.length;
179
+
180
+ useEffect(() => {
181
+ const activity = STAGE_ACTIVITY[stage];
182
+ if (activity) recordResearchActivity(activity);
183
+ }, [stage]);
184
+
185
+ useEffect(() => {
186
+ if (stage === "portfolio" && positionCount > 0) recordResearchActivity("onboarding_position_added");
187
+ }, [positionCount, stage]);
188
+
189
+ // The portfolio step opens straight into the ticker field.
190
+ useEffect(() => {
191
+ if (stage === "portfolio" && portfolioSub === "positions") setEditingField(true);
192
+ }, [portfolioSub, stage]);
193
+
194
+ /**
195
+ * Seeds the watchlist and swaps Home for the first-run workspace built
196
+ * around `symbol`. The config comes back for the caller to persist with its
197
+ * own progress patch.
198
+ */
199
+ const buildFirstRunWorkspace = useCallback(async (
200
+ baseConfig: AppConfig,
201
+ symbol: string,
202
+ portfolioId: string,
203
+ ): Promise<AppConfig> => {
204
+ let config = baseConfig;
205
+ let watchlistId = config.watchlists[0]?.id;
206
+ if (!watchlistId) {
207
+ watchlistId = "watchlist";
208
+ config = { ...config, watchlists: [{ id: watchlistId, name: "Watchlist" }] };
209
+ }
210
+ const plan = planFirstRunWatchlist(stateRef.current.tickers, watchlistId, portfolioId);
211
+ for (const metadata of plan.create) {
212
+ try {
213
+ const ticker = await pluginRegistry.tickerRepository.createTicker(metadata);
214
+ dispatch({ type: "UPDATE_TICKER", ticker });
215
+ pluginRegistry.events.emit("ticker:added", { symbol: ticker.metadata.ticker, ticker });
216
+ } catch (error) {
217
+ onboardingLog.error("First-run watchlist seed failed", { symbol: metadata.ticker, error: String(error) });
218
+ }
219
+ }
220
+ for (const ticker of plan.update) {
221
+ try {
222
+ await pluginRegistry.tickerRepository.saveTicker(ticker);
223
+ dispatch({ type: "UPDATE_TICKER", ticker });
224
+ } catch (error) {
225
+ onboardingLog.error("First-run watchlist update failed", { symbol: ticker.metadata.ticker, error: String(error) });
226
+ }
227
+ }
228
+ const home = buildFirstRunLayout({
229
+ symbol,
230
+ portfolioId,
231
+ watchlistId,
232
+ hasPane: (paneId) => pluginRegistry.panes?.has(paneId) ?? false,
233
+ });
234
+ return applyFirstRunLayout(config, home);
235
+ }, [dispatch, pluginRegistry, stateRef]);
236
+
237
+ const commitWorkspaceProgress = useCallback(async (
238
+ nextConfig: AppConfig,
239
+ patch: Partial<OnboardingProgress> & Pick<OnboardingProgress, "stage">,
240
+ ) => {
241
+ const withProgress = withOnboardingProgress(nextConfig, patch);
242
+ await saveConfigImmediately(withProgress);
243
+ dispatch({ type: "SET_CONFIG", config: withProgress });
244
+ pluginRegistry.events.emit("config:changed", { config: withProgress });
245
+ }, [dispatch, pluginRegistry.events]);
246
+
247
+ const continueFromPositions = useCallback(() => {
248
+ const largest = pickLargestPosition(positions.positions);
249
+ if (!largest) {
250
+ positions.focusField(0);
251
+ return;
252
+ }
253
+ setEditingField(false);
254
+ setPersistenceError(null);
255
+ void (async () => {
256
+ try {
257
+ const nextConfig = await buildFirstRunWorkspace(stateRef.current.config, largest.symbol, positions.portfolioId);
258
+ if (finishingRef.current) return;
259
+ await commitWorkspaceProgress(nextConfig, {
260
+ stage: "research",
261
+ path: "manual",
262
+ portfolioId: positions.portfolioId,
263
+ tickerSymbol: largest.symbol,
264
+ positionsImported: positions.positions.length,
265
+ brokerName: undefined,
266
+ });
267
+ } catch (error) {
268
+ setPersistenceError(error instanceof Error ? error.message : String(error));
269
+ }
270
+ })();
271
+ }, [buildFirstRunWorkspace, commitWorkspaceProgress, positions, stateRef]);
272
+
159
273
  const handleBrokerSynced = useCallback(async (
160
274
  result: SyncBrokerInstanceResult,
161
275
  syncedConfig: AppConfig,
162
276
  ) => {
163
277
  if (finishingRef.current) return;
164
- const tickerSymbol = result.positions.find((position) => position.ticker)?.ticker
278
+ const tickerSymbol = pickLargestBrokerPosition(result.positions)?.ticker
165
279
  ?? result.addedTickers[0]?.metadata.ticker
166
280
  ?? result.updatedTickers[0]?.metadata.ticker;
167
281
  const brokerName = brokerOptions.find((option) => option.id === selectedBrokerId)?.name;
168
- const nextConfig = withOnboardingProgress(syncedConfig, {
169
- stage: tickerSymbol ? "research" : "add-ticker",
282
+ const portfolioId = tickerSymbol ? (result.portfolioIds[0] ?? "main") : "main";
283
+ dispatch({ type: "SET_TICKERS", tickers: result.tickers });
284
+ const workspaceConfig = tickerSymbol
285
+ ? await buildFirstRunWorkspace(syncedConfig, tickerSymbol, portfolioId)
286
+ : syncedConfig;
287
+ await commitWorkspaceProgress(workspaceConfig, {
288
+ stage: tickerSymbol ? "research" : "portfolio",
170
289
  path: "broker",
171
- portfolioId: tickerSymbol ? (result.portfolioIds[0] ?? "main") : "main",
290
+ portfolioId,
172
291
  tickerSymbol,
173
292
  brokerName,
174
293
  positionsImported: result.positions.length,
175
294
  });
176
- await saveConfigImmediately(nextConfig);
177
- dispatch({ type: "SET_CONFIG", config: nextConfig });
178
- dispatch({ type: "SET_TICKERS", tickers: result.tickers });
179
- pluginRegistry.events.emit("config:changed", { config: nextConfig });
180
295
  setEditingField(false);
181
- setPortfolioSub("choose");
182
- }, [brokerOptions, dispatch, pluginRegistry.events, selectedBrokerId]);
296
+ setPortfolioSub("positions");
297
+ }, [brokerOptions, buildFirstRunWorkspace, commitWorkspaceProgress, dispatch, selectedBrokerId]);
183
298
 
184
299
  const {
185
300
  isBrokerSyncing,
@@ -198,7 +313,7 @@ export function OnboardingWizard({ pluginRegistry, importBrokerPositions, onComp
198
313
  setPortfolioSub,
199
314
  });
200
315
 
201
- const finish = useCallback(async () => {
316
+ const finish = useCallback(async (skipped = false) => {
202
317
  if (finishingRef.current) return;
203
318
  if (!resetBrokerSync()) return;
204
319
  finishingRef.current = true;
@@ -217,6 +332,7 @@ export function OnboardingWizard({ pluginRegistry, importBrokerPositions, onComp
217
332
  complete: true,
218
333
  progress: undefined,
219
334
  });
335
+ recordResearchActivity(skipped ? "onboarding_skipped" : "onboarding_completed");
220
336
  await Promise.resolve(onComplete(nextConfig));
221
337
  } catch (error) {
222
338
  setPersistenceError(error instanceof Error ? error.message : String(error));
@@ -224,6 +340,7 @@ export function OnboardingWizard({ pluginRegistry, importBrokerPositions, onComp
224
340
  setIsFinishing(false);
225
341
  }
226
342
  }, [dispatch, onComplete, resetBrokerSync, stateRef]);
343
+ const skipSetup = useCallback(() => { void finish(true); }, [finish]);
227
344
 
228
345
  useEffect(() => {
229
346
  if (!selectedBrokerId) return;
@@ -238,33 +355,18 @@ export function OnboardingWizard({ pluginRegistry, importBrokerPositions, onComp
238
355
  if (!editingField) return;
239
356
  const timer = setTimeout(() => inputRef.current?.focus?.(), 10);
240
357
  return () => clearTimeout(timer);
241
- }, [account.accountFieldIdx, account.accountSub, brokerFieldIdx, editingField, portfolioSub]);
358
+ }, [account.accountFieldIdx, account.accountSub, brokerFieldIdx, editingField, portfolioSub, positions.fieldIdx]);
242
359
 
243
360
  useEffect(() => {
244
361
  if (stage !== "account") return;
245
362
  account.syncExistingAccountSession();
246
363
  }, [account.syncExistingAccountSession, stage]);
247
364
 
248
- useEffect(() => pluginRegistry.events.on(
249
- "command-bar:portfolio-membership-persisted",
250
- ({ symbol, portfolioId }) => {
251
- const current = getOnboardingProgress(stateRef.current.config);
252
- if (current.stage !== "add-ticker" || portfolioId !== current.portfolioId) return;
253
- saveProgressInBackground({
254
- stage: "research",
255
- path: current.path,
256
- portfolioId,
257
- tickerSymbol: symbol,
258
- });
259
- },
260
- ), [pluginRegistry.events, saveProgressInBackground, stateRef]);
261
-
262
365
  useEffect(() => {
263
366
  if (stage !== "research" || !progress.tickerSymbol || researchOpenedRef.current === progress.tickerSymbol) return;
264
367
  researchOpenedRef.current = progress.tickerSymbol;
265
- pluginRegistry.navigateTicker(progress.tickerSymbol, { sourcePaneId: "ticker-detail:main" });
266
368
  recordResearchActivity("ticker_saved");
267
- }, [stage, progress.tickerSymbol, pluginRegistry]);
369
+ }, [stage, progress.tickerSymbol]);
268
370
 
269
371
  useEffect(() => {
270
372
  if (stage !== "upgrade" || pricing) return;
@@ -295,37 +397,34 @@ export function OnboardingWizard({ pluginRegistry, importBrokerPositions, onComp
295
397
  }));
296
398
  }, [resetBrokerSync]);
297
399
 
298
- const choosePortfolioPath = useCallback((choiceIndex = portfolioOptionIdx) => {
299
- const choice = portfolioChoices[choiceIndex];
300
- if (!choice || choice.id === "manual") {
301
- resetBrokerSync();
302
- setSelectedBrokerId(null);
303
- saveProgressInBackground({
304
- stage: "add-ticker",
305
- path: "manual",
306
- portfolioId: config.portfolios.find((portfolio) => !portfolio.brokerInstanceId)?.id ?? "main",
307
- });
308
- return;
309
- }
310
-
400
+ const selectBroker = useCallback((brokerId: string) => {
311
401
  resetBrokerSync();
312
- setSelectedBrokerId(choice.id);
402
+ setSelectedBrokerId(brokerId);
313
403
  setBrokerFieldIdx(0);
314
404
  setPortfolioSub("broker-fields");
315
- const broker = brokerOptions.find((option) => option.id === choice.id);
405
+ const broker = brokerOptions.find((option) => option.id === brokerId);
316
406
  const firstField = broker
317
- ? resolveBrokerConfigFields(broker.adapter, brokerValues[choice.id] ?? {}).filter((field) => field.required)[0]
407
+ ? resolveBrokerConfigFields(broker.adapter, brokerValues[brokerId] ?? {}).filter((field) => field.required)[0]
318
408
  : null;
319
409
  setEditingField(firstField?.type !== "select");
320
- }, [
321
- brokerOptions,
322
- brokerValues,
323
- config.portfolios,
324
- portfolioChoices,
325
- portfolioOptionIdx,
326
- resetBrokerSync,
327
- saveProgressInBackground,
328
- ]);
410
+ }, [brokerOptions, brokerValues, resetBrokerSync]);
411
+
412
+ const chooseBroker = useCallback((choiceIndex = portfolioOptionIdx) => {
413
+ const choice = brokerChoices[choiceIndex];
414
+ if (choice) selectBroker(choice.id);
415
+ }, [brokerChoices, portfolioOptionIdx, selectBroker]);
416
+
417
+ /** Broker import is the secondary path: one broker goes straight to its fields. */
418
+ const openBrokerConnect = useCallback(() => {
419
+ if (brokerOptions.length === 0) return;
420
+ setEditingField(false);
421
+ if (brokerOptions.length === 1) {
422
+ selectBroker(brokerOptions[0]!.id);
423
+ return;
424
+ }
425
+ setPortfolioOptionIdx(0);
426
+ setPortfolioSub("choose");
427
+ }, [brokerOptions, selectBroker]);
329
428
 
330
429
  const submitBrokerField = useCallback(() => {
331
430
  if (!selectedBrokerId || isBrokerSyncing) return;
@@ -390,8 +489,12 @@ export function OnboardingWizard({ pluginRegistry, importBrokerPositions, onComp
390
489
  ]);
391
490
 
392
491
  const continuePortfolio = useCallback(() => {
492
+ if (portfolioSub === "positions") {
493
+ continueFromPositions();
494
+ return;
495
+ }
393
496
  if (portfolioSub === "choose") {
394
- choosePortfolioPath();
497
+ chooseBroker();
395
498
  return;
396
499
  }
397
500
  if (portfolioSub === "broker-setup") {
@@ -408,7 +511,8 @@ export function OnboardingWizard({ pluginRegistry, importBrokerPositions, onComp
408
511
  activeBrokerFields,
409
512
  brokerFieldIdx,
410
513
  brokerSyncError,
411
- choosePortfolioPath,
514
+ chooseBroker,
515
+ continueFromPositions,
412
516
  isBrokerSyncing,
413
517
  portfolioSub,
414
518
  submitBrokerField,
@@ -416,64 +520,41 @@ export function OnboardingWizard({ pluginRegistry, importBrokerPositions, onComp
416
520
  ]);
417
521
 
418
522
  const backPortfolio = useCallback(() => {
419
- if (portfolioSub === "choose") return;
523
+ if (portfolioSub === "positions") return;
420
524
  if (portfolioSub === "broker-sync" && !resetBrokerSync()) return;
421
- setPortfolioSub("choose");
525
+ setPortfolioSub("positions");
526
+ setSelectedBrokerId(null);
422
527
  setBrokerFieldIdx(0);
423
528
  setEditingField(false);
424
529
  }, [portfolioSub, resetBrokerSync]);
425
530
 
426
- const activateAccountChoice = useCallback((index: number) => {
427
- const choice = ACCOUNT_CHOICE_IDS[index];
428
- if (!choice || choice === "skip") {
429
- saveProgressInBackground({ stage: "ready", accountStatus: "skipped" });
430
- return;
431
- }
432
- if (choice === "qr") {
433
- account.beginQrSignIn();
434
- return;
435
- }
436
- account.beginAccountMode(choice);
437
- }, [account.beginAccountMode, account.beginQrSignIn, saveProgressInBackground]);
438
-
439
531
  const submitAccountField = useCallback(() => {
440
532
  setEditingField(false);
441
533
  account.submitAccountField();
442
534
  }, [account.submitAccountField]);
443
535
 
444
536
  const continueAccount = useCallback(() => {
445
- if (account.accountSub === "choose") {
446
- activateAccountChoice(account.accountChoiceIdx);
447
- return;
448
- }
449
537
  // The QR panel owns enter (retry after a denial); approval advances itself.
450
538
  if (account.accountSub === "qr") return;
451
539
  if (account.accountSub === "signed-in") {
452
- saveProgressInBackground({ stage: apiClient.getCurrentUser()?.emailVerified ? "upgrade" : "verify", accountStatus: "signed-in" });
453
- return;
454
- }
455
- if (account.accountSubmitError?.kind === "switch-to-login") {
456
- account.switchToAccountLogin();
540
+ saveProgressInBackground({ stage: "upgrade", accountStatus: "signed-in" });
457
541
  return;
458
542
  }
459
543
  submitAccountField();
460
- }, [
461
- account.accountChoiceIdx,
462
- account.accountSub,
463
- account.accountSubmitError?.kind,
464
- account.switchToAccountLogin,
465
- activateAccountChoice,
466
- saveProgressInBackground,
467
- submitAccountField,
468
- ]);
544
+ }, [account.accountSub, saveProgressInBackground, submitAccountField]);
545
+
546
+ // The account step opens on the email form with the cursor in it.
547
+ useEffect(() => {
548
+ if (stage === "account" && (account.accountSub === "signup" || account.accountSub === "login")) setEditingField(true);
549
+ }, [account.accountSub, stage]);
469
550
 
470
551
  const startUpgrade = useCallback(() => {
471
552
  void persistProgress({
472
553
  stage: "upgrade",
473
554
  accountStatus: progress.accountStatus,
474
555
  checkoutOpenedAt: new Date().toISOString(),
475
- }).then(() => openUpgrade()).catch(() => {});
476
- }, [openUpgrade, persistProgress, progress.accountStatus]);
556
+ }).then(() => openUpgrade({ interval: billingInterval })).catch(() => {});
557
+ }, [billingInterval, openUpgrade, persistProgress, progress.accountStatus]);
477
558
 
478
559
  const primaryUpgradeAction = useCallback(() => {
479
560
  if (planAccess.hasProAccess) {
@@ -497,23 +578,21 @@ export function OnboardingWizard({ pluginRegistry, importBrokerPositions, onComp
497
578
  if (finishingRef.current || isBrokerCommitting) return;
498
579
  setEditingField(false);
499
580
  if (section === "portfolio") {
500
- account.returnToAccountChooser();
501
- setPortfolioSub("choose");
581
+ setPortfolioSub("positions");
502
582
  saveProgressInBackground({ stage: "portfolio" });
503
583
  return;
504
584
  }
505
585
  if (section === "cloud") {
506
- account.returnToAccountChooser();
507
586
  saveProgressInBackground({ stage: "account" });
508
587
  return;
509
588
  }
510
589
  if (planAccess.signedIn) {
511
590
  saveProgressInBackground({ stage: "upgrade", accountStatus: "signed-in" });
512
591
  }
513
- }, [account.returnToAccountChooser, isBrokerCommitting, planAccess.signedIn, saveProgressInBackground]);
592
+ }, [isBrokerCommitting, planAccess.signedIn, saveProgressInBackground]);
514
593
 
515
594
  const sectionAvailability: Partial<Record<OnboardingSectionId, boolean>> = {
516
- portfolio: !isBrokerCommitting && stage !== "welcome",
595
+ portfolio: !isBrokerCommitting,
517
596
  cloud: !isBrokerCommitting && (stage === "account" || stage === "upgrade" || stage === "ready" || !!progress.tickerSymbol),
518
597
  pro: !isBrokerCommitting && planAccess.signedIn && (
519
598
  stage === "upgrade"
@@ -523,7 +602,7 @@ export function OnboardingWizard({ pluginRegistry, importBrokerPositions, onComp
523
602
  };
524
603
 
525
604
  useShortcut((event) => {
526
- if (helpFocused || commandBarOpen) return;
605
+ if (helpFocused) return;
527
606
  const name = event.name ?? event.key ?? "";
528
607
  const enter = name === "enter" || name === "return";
529
608
  const escape = name === "escape" || name === "backspace";
@@ -534,45 +613,57 @@ export function OnboardingWizard({ pluginRegistry, importBrokerPositions, onComp
534
613
 
535
614
  if (name === "f10") {
536
615
  consume();
537
- if (stage === "portfolio" || stage === "add-ticker") return;
616
+ if (stage === "portfolio") return;
538
617
  if (!isBrokerCommitting) {
539
618
  if (stage === "upgrade" && !planAccess.hasProAccess) continueFree();
540
- else void finish();
619
+ else void finish(true);
541
620
  }
542
621
  return;
543
622
  }
544
623
 
545
- if (editingField) {
624
+ if (stage === "portfolio" && portfolioSub === "positions") {
625
+ if (editingField) {
626
+ if (enter) {
627
+ consume();
628
+ positions.submitField();
629
+ } else if (name === "tab") {
630
+ consume();
631
+ positions.setFieldIdx((index) => (
632
+ event.shift ? Math.max(0, index - 1) : Math.min(POSITION_FIELDS.length - 1, index + 1)
633
+ ));
634
+ } else if (name === "escape") {
635
+ consume();
636
+ setEditingField(false);
637
+ }
638
+ return;
639
+ }
546
640
  if (enter) {
547
641
  consume();
548
- if (stage === "portfolio") submitBrokerField();
549
- else if (stage === "account") submitAccountField();
550
- } else if (name === "escape") {
642
+ if (positionCount > 0) continueFromPositions();
643
+ else positions.focusField(0);
644
+ } else if (name === "a") {
551
645
  consume();
552
- setEditingField(false);
553
- if (stage === "account") account.returnToAccountChooser();
554
- else if (stage === "portfolio") setPortfolioSub("choose");
646
+ positions.focusField(0);
647
+ } else if (name === "b" && positionCount > 0) {
648
+ consume();
649
+ openBrokerConnect();
555
650
  }
556
651
  return;
557
652
  }
558
653
 
559
- if (stage === "welcome") {
654
+ if (editingField) {
560
655
  if (enter) {
561
656
  consume();
562
- saveProgressInBackground({ stage: "portfolio" });
657
+ if (stage === "portfolio") submitBrokerField();
658
+ else if (stage === "account") submitAccountField();
563
659
  } else if (name === "escape") {
564
660
  consume();
565
- void finish();
566
- }
567
- return;
568
- }
569
- if (stage === "add-ticker") {
570
- if (name === "escape" || name === "backspace") {
571
- consume();
572
- goToSection("portfolio");
661
+ setEditingField(false);
662
+ if (stage === "portfolio") backPortfolio();
573
663
  }
574
664
  return;
575
665
  }
666
+
576
667
  if (stage === "portfolio") {
577
668
  if (enter) {
578
669
  consume();
@@ -586,7 +677,7 @@ export function OnboardingWizard({ pluginRegistry, importBrokerPositions, onComp
586
677
  else if (activeBrokerFields[brokerFieldIdx]?.type === "select") setBrokerSelectIdx((index) => Math.max(0, index - 1));
587
678
  } else if (name === "down" || name === "j") {
588
679
  consume();
589
- if (portfolioSub === "choose") setPortfolioOptionIdx((index) => Math.min(portfolioChoices.length - 1, index + 1));
680
+ if (portfolioSub === "choose") setPortfolioOptionIdx((index) => Math.min(brokerChoices.length - 1, index + 1));
590
681
  else if (activeBrokerFields[brokerFieldIdx]?.type === "select") {
591
682
  const optionCount = activeBrokerFields[brokerFieldIdx]?.options?.length ?? 0;
592
683
  setBrokerSelectIdx((index) => Math.min(Math.max(0, optionCount - 1), index + 1));
@@ -605,14 +696,11 @@ export function OnboardingWizard({ pluginRegistry, importBrokerPositions, onComp
605
696
  continueAccount();
606
697
  } else if (escape) {
607
698
  consume();
608
- if (account.accountSub !== "choose") account.returnToAccountChooser();
699
+ if (account.accountSub === "qr" || account.accountSub === "login") account.returnToAccountForm();
609
700
  else goToSection("portfolio");
610
- } else if (account.accountSub === "choose" && (name === "up" || name === "k")) {
611
- consume();
612
- account.setAccountChoiceIdx((index) => Math.max(0, index - 1));
613
- } else if (account.accountSub === "choose" && (name === "down" || name === "j")) {
701
+ } else if (name === "b" && account.accountSub !== "qr" && account.accountSub !== "signed-in") {
614
702
  consume();
615
- account.setAccountChoiceIdx((index) => Math.min(ACCOUNT_CHOICE_IDS.length - 1, index + 1));
703
+ account.beginQrSignIn();
616
704
  }
617
705
  return;
618
706
  }
@@ -637,126 +725,75 @@ export function OnboardingWizard({ pluginRegistry, importBrokerPositions, onComp
637
725
  }
638
726
  }, { phase: "before", allowEditable: true });
639
727
 
640
- const portfolioActionLabel = portfolioSub === "broker-sync"
641
- ? (isBrokerSyncing ? t("Importing...") : t("Retry"))
642
- : t("Continue");
643
-
644
- if (helpFocused || (stage === "add-ticker" && commandBarOpen)) {
728
+ if (helpFocused) {
645
729
  return null;
646
730
  }
647
731
 
648
732
  if (stage === "research") {
649
- return <OnboardingCoach step={t("YOUR FIRST RESEARCH WORKSPACE")}
650
- title={tf("Explore {ticker}", { ticker: progress.tickerSymbol ?? "your company" })}
733
+ const ticker = progress.tickerSymbol ?? t("your company");
734
+ return <OnboardingCoach step={t("YOUR WORKSPACE")}
735
+ title={tf("Built around {ticker}", { ticker })}
651
736
  actions={<><OnboardingButton label="Keep exploring" variant="ghost" onPress={() => { void finish(); }} />
652
737
  <OnboardingButton label="Connect free Cloud" variant="primary" onPress={() => saveProgressInBackground({ stage: "account" })} /></>}>
653
- <Text fg={colors.textDim} wrapText>{t("Your company is saved. Explore the chart and financials now. Connect Cloud when you're ready for synced layouts, news and Pro research.")}</Text>
738
+ <Text fg={colors.textDim} wrapText>{tf("Your holdings as a heatmap, a watchlist, and {ticker} charted. Every pane moves; {shortcut} adds more.", {
739
+ ticker,
740
+ shortcut: commandBarShortcut,
741
+ })}</Text>
654
742
  </OnboardingCoach>;
655
743
  }
656
744
 
657
- if (stage === "verify") {
658
- return <OnboardingModal width={66} height={14}>
659
- <OnboardingTitle step={t("CONNECT CLOUD")} title={t("Check your email")}
660
- description={apiClient.getCurrentUser()?.email ?? account.accountEmail} />
661
- <CloudVerificationPanel onVerified={() => {
662
- void chatController.refreshSession();
663
- saveProgressInBackground({ stage: "upgrade", accountStatus: "signed-in" });
664
- }} onContinueFree={() => { void finish(); }} />
665
- </OnboardingModal>;
666
- }
667
-
668
- if (stage === "add-ticker") {
669
- return (
670
- <OnboardingCoach
671
- step={t("PORTFOLIO SETUP")}
672
- title={t("Add one company you follow")}
673
- actions={(
674
- <>
675
- <OnboardingButton label="Back" variant="ghost" onPress={() => goToSection("portfolio")} />
676
- <OnboardingButton
677
- label="Open command bar"
678
- variant="primary"
679
- shortcut="AP"
680
- onPress={() => pluginRegistry.openCommandBar("AP ")}
681
- />
682
- </>
683
- )}
684
- >
685
- <Text fg={colors.textDim} wrapText>
686
- {t("Use AP in the real command bar and choose any ticker. Setup continues as soon as the company is saved to your portfolio.")}
687
- </Text>
688
- </OnboardingCoach>
689
- );
690
- }
691
-
692
- if (stage === "welcome") {
693
- return (
694
- <OnboardingModal width={64} height={12}>
695
- <OnboardingHeader
696
- onDismiss={() => { void finish(); }}
697
- dismissing={isFinishing}
698
- />
699
- <OnboardingTitle
700
- step={t("WELCOME")}
701
- title={t("Make Gloomberb yours")}
702
- description={t("Pick a company. Explore its chart and financials. Keep your workspace free, or add Pro research when you need it.")}
703
- />
704
- {persistenceError ? (
705
- <Text fg={colors.negative} wrapText style={desktop ? { marginTop: 10 } : undefined}>
706
- {persistenceError}
707
- </Text>
708
- ) : null}
709
- <OnboardingActions>
710
- <OnboardingButton
711
- label="Research my first company"
712
- variant="primary"
713
- onPress={() => saveProgressInBackground({ stage: "portfolio" })}
714
- />
715
- </OnboardingActions>
716
- </OnboardingModal>
717
- );
718
- }
719
-
720
745
  if (stage === "portfolio") {
721
746
  const selectedBrokerName = selectedBrokerId
722
747
  ? brokerOptions.find((option) => option.id === selectedBrokerId)?.name
723
748
  : null;
724
- const portfolioModalHeight = portfolioSub === "choose"
725
- ? 18
726
- : portfolioSub === "broker-setup"
727
- ? 21
728
- : portfolioSub === "broker-sync"
729
- ? 14
730
- : 20;
749
+ const portfolioModalHeight = portfolioSub === "positions"
750
+ ? 22
751
+ : portfolioSub === "choose"
752
+ ? 16
753
+ : portfolioSub === "broker-setup"
754
+ ? 21
755
+ : portfolioSub === "broker-sync"
756
+ ? 14
757
+ : 20;
758
+ const title = portfolioSub === "positions"
759
+ ? t("What do you hold?")
760
+ : portfolioSub === "choose"
761
+ ? t("Connect a broker")
762
+ : selectedBrokerName
763
+ ? tf("Connect {broker}", { broker: selectedBrokerName })
764
+ : t("Set up a portfolio");
765
+ const description = portfolioSub === "positions"
766
+ ? undefined
767
+ : portfolioSub === "choose"
768
+ ? t("Credentials stay on this device.")
769
+ : t("Enter the connection details for this broker. Credentials stay on this device.");
731
770
  return (
732
- <OnboardingModal width={70} height={portfolioModalHeight}>
771
+ <OnboardingModal width={76} height={portfolioModalHeight} desktopWidth="min(620px, 100%)">
733
772
  <OnboardingHeader
734
773
  active="portfolio"
735
774
  available={sectionAvailability}
736
775
  onNavigate={goToSection}
737
- onDismiss={() => { void finish(); }}
776
+ onDismiss={skipSetup}
738
777
  dismissing={isFinishing}
739
778
  dismissDisabled={isBrokerCommitting}
740
779
  showDismiss={false}
741
780
  />
742
781
  <OnboardingTitle
743
782
  step={desktop ? undefined : t("PORTFOLIO")}
744
- title={portfolioSub === "choose"
745
- ? t("How do you want to start?")
746
- : selectedBrokerName
747
- ? tf("Connect {broker}", { broker: selectedBrokerName })
748
- : t("Set up a portfolio")}
749
- description={portfolioSub === "choose"
750
- ? t("Create a manual portfolio and add one ticker, or import positions from a supported broker.")
751
- : t("Enter the connection details for this broker. Credentials stay on this device.")}
783
+ title={title}
784
+ description={description}
752
785
  />
753
786
  <Box minHeight={0}>
754
787
  <PortfolioStep
755
788
  sub={portfolioSub}
756
- choices={portfolioChoices}
789
+ positions={positions}
790
+ positionsInputRef={inputRef}
791
+ positionsEditing={editingField}
792
+ commandBarShortcut={commandBarShortcut}
793
+ choices={brokerChoices}
757
794
  optionIdx={portfolioOptionIdx}
758
795
  onOptionSelect={setPortfolioOptionIdx}
759
- onOptionActivate={choosePortfolioPath}
796
+ onOptionActivate={chooseBroker}
760
797
  selectedBrokerId={selectedBrokerId}
761
798
  brokerFields={activeBrokerFields}
762
799
  brokerFieldIdx={brokerFieldIdx}
@@ -764,7 +801,6 @@ export function OnboardingWizard({ pluginRegistry, importBrokerPositions, onComp
764
801
  onBrokerSelect={setBrokerSelectIdx}
765
802
  brokerValues={brokerValues}
766
803
  onBrokerFieldChange={setBrokerFieldValue}
767
- onSubmitBrokerField={submitBrokerField}
768
804
  editing={editingField}
769
805
  inputRef={inputRef}
770
806
  brokerSyncing={isBrokerSyncing}
@@ -776,18 +812,32 @@ export function OnboardingWizard({ pluginRegistry, importBrokerPositions, onComp
776
812
  {persistenceError}
777
813
  </Text>
778
814
  ) : null}
779
- <OnboardingActions>
780
- {portfolioSub !== "choose" ? (
781
- <OnboardingButton label="Back" variant="ghost" disabled={isBrokerCommitting} onPress={backPortfolio} />
782
- ) : null}
783
- {!desktop || portfolioSub !== "choose" ? (
784
- <OnboardingButton
785
- label={portfolioActionLabel}
786
- variant="primary"
787
- disabled={isBrokerSyncing}
788
- onPress={continuePortfolio}
789
- />
790
- ) : null}
815
+ <OnboardingActions hint={portfolioSub === "positions" && desktop ? tf("Later: {shortcut}, then AP.", { shortcut: commandBarShortcut }) : undefined}>
816
+ {portfolioSub === "positions" ? (
817
+ <>
818
+ {brokerOptions.length > 0 && positionCount > 0 ? (
819
+ <OnboardingButton label="Connect a broker" variant="ghost" onPress={openBrokerConnect} />
820
+ ) : null}
821
+ <OnboardingButton
822
+ label="Continue"
823
+ variant="primary"
824
+ disabled={positionCount === 0 || positions.submitting}
825
+ onPress={continueFromPositions}
826
+ />
827
+ </>
828
+ ) : (
829
+ <>
830
+ <OnboardingButton label="Back" variant="ghost" disabled={isBrokerCommitting} onPress={backPortfolio} />
831
+ {!desktop || portfolioSub !== "choose" ? (
832
+ <OnboardingButton
833
+ label={portfolioSub === "broker-sync" ? (isBrokerSyncing ? t("Importing...") : t("Retry")) : t("Continue")}
834
+ variant="primary"
835
+ disabled={isBrokerSyncing}
836
+ onPress={continuePortfolio}
837
+ />
838
+ ) : null}
839
+ </>
840
+ )}
791
841
  </OnboardingActions>
792
842
  </OnboardingModal>
793
843
  );
@@ -798,40 +848,32 @@ export function OnboardingWizard({ pluginRegistry, importBrokerPositions, onComp
798
848
  ? t("See Pro plans")
799
849
  : account.accountSub === "login"
800
850
  ? t("Log in")
801
- : account.accountSub === "signup"
802
- ? (account.accountFieldIdx > 0 ? t("Sign up free") : t("Continue"))
803
- : t("Continue");
851
+ : t("Continue");
804
852
  const accountTitle = account.accountSub === "signup"
805
- ? t("Create your free account")
853
+ ? t("Connect Gloom Cloud")
806
854
  : account.accountSub === "login"
807
855
  ? t("Log in")
808
856
  : account.accountSub === "qr"
809
857
  ? t("Continue in browser")
810
- : account.accountSub === "signed-in"
811
- ? t("Connected")
812
- : t("Sync across apps");
813
- const accountDescription = account.accountSub === "choose"
814
- ? t("Sync your layouts. Search calls, news and filings.")
815
- : account.accountSub === "qr"
816
- ? t("Open the sign-in link, or scan the code with your phone.")
817
- : account.accountSub === "signup"
818
- ? t("Create the free account now. Cloud features unlock after you verify your email.")
858
+ : t("Connected");
859
+ const accountDescription = account.accountSub === "qr"
860
+ ? t("Open the sign-in link, or scan the code with your phone.")
861
+ : account.accountSub === "signup"
862
+ ? t("Gloom Cloud adds the data layer: quotes, news, filings and Ask Gloom, synced to every device. Free account.")
819
863
  : account.accountSub === "login"
820
- ? t("Use the account that should own this workspace and its synced data.")
821
- : t("Your account is ready. Next, choose whether you want the real-time Pro data plan.");
864
+ ? t("Enter the password for this account.")
865
+ : t("Next: real-time Pro data.");
822
866
  const accountStatusRows = account.accountSubmitting || account.accountValidationError || account.accountSubmitError
823
867
  ? 1
824
868
  : 0;
825
- const accountSwitchRows = account.accountSubmitError?.kind === "switch-to-login" ? 1 : 0;
826
869
  // The QR grid is the tallest thing this wizard ever shows; DeviceSignInPanel
827
870
  // degrades to the code plus URL when the terminal cannot give it these rows.
828
- const accountModalHeight = account.accountSub === "choose"
829
- ? 21
830
- : account.accountSub === "qr"
831
- ? 32
832
- : account.accountSub === "signed-in"
833
- ? 12
834
- : 16 + (account.accountFieldIdx > 0 ? 2 : 0) + accountStatusRows + accountSwitchRows;
871
+ const accountModalHeight = account.accountSub === "qr"
872
+ ? 32
873
+ : account.accountSub === "signed-in"
874
+ ? 12
875
+ : 17 + (account.accountFieldIdx > 0 ? 2 : 0) + accountStatusRows;
876
+ const browserSignIn = account.accountSub === "signup" || account.accountSub === "login";
835
877
  // OnboardingModal clamps the card to the viewport, so the panel has to size
836
878
  // off the clamped height or the QR overflows a short terminal.
837
879
  const accountPanelHeight = Math.max(4, Math.min(accountModalHeight, viewportHeight - 2) - 9);
@@ -844,7 +886,7 @@ export function OnboardingWizard({ pluginRegistry, importBrokerPositions, onComp
844
886
  active="cloud"
845
887
  available={sectionAvailability}
846
888
  onNavigate={goToSection}
847
- onDismiss={() => { void finish(); }}
889
+ onDismiss={skipSetup}
848
890
  dismissing={isFinishing}
849
891
  />
850
892
  <OnboardingTitle
@@ -855,9 +897,6 @@ export function OnboardingWizard({ pluginRegistry, importBrokerPositions, onComp
855
897
  <Box minHeight={0}>
856
898
  <AccountStep
857
899
  sub={account.accountSub}
858
- choiceIdx={account.accountChoiceIdx}
859
- onChoiceSelect={account.setAccountChoiceIdx}
860
- onChoiceActivate={activateAccountChoice}
861
900
  email={account.accountEmail}
862
901
  password={account.accountPassword}
863
902
  fieldIdx={account.accountFieldIdx}
@@ -870,7 +909,6 @@ export function OnboardingWizard({ pluginRegistry, importBrokerPositions, onComp
870
909
  onEmailChange={account.setAccountEmail}
871
910
  onPasswordChange={account.setAccountPassword}
872
911
  onFieldFocus={account.focusAccountField}
873
- onSubmitField={submitAccountField}
874
912
  onQrApproved={account.completeQrSignIn}
875
913
  height={accountPanelHeight}
876
914
  />
@@ -880,13 +918,22 @@ export function OnboardingWizard({ pluginRegistry, importBrokerPositions, onComp
880
918
  {persistenceError}
881
919
  </Text>
882
920
  ) : null}
883
- <OnboardingActions>
921
+ {!desktop && browserSignIn ? (
922
+ <Box height={1}>
923
+ <Text fg={colors.textMuted}>{t("b: sign in with the browser instead")}</Text>
924
+ </Box>
925
+ ) : null}
926
+ <OnboardingActions
927
+ hint={desktop && browserSignIn ? (
928
+ <Button label="Sign in with the browser instead" variant="plain" compact onPress={account.beginQrSignIn} />
929
+ ) : undefined}
930
+ >
884
931
  <OnboardingButton
885
932
  label="Back"
886
933
  variant="ghost"
887
- onPress={account.accountSub === "choose" ? () => goToSection("portfolio") : account.returnToAccountChooser}
934
+ onPress={account.accountSub === "qr" || account.accountSub === "login" ? account.returnToAccountForm : () => goToSection("portfolio")}
888
935
  />
889
- {account.accountSub !== "qr" && (!desktop || account.accountSub !== "choose") ? (
936
+ {account.accountSub !== "qr" ? (
890
937
  <OnboardingButton
891
938
  label={accountActionLabel}
892
939
  variant="primary"
@@ -901,41 +948,73 @@ export function OnboardingWizard({ pluginRegistry, importBrokerPositions, onComp
901
948
 
902
949
  if (stage === "upgrade") {
903
950
  const primaryLabel = planAccess.hasProAccess ? t("Continue with Pro") : t("Start 7-day free trial");
904
- const monthlyPrice = formatCloudMonthlyPrice(pricing);
951
+ const price = formatCloudPrice(pricing, billingInterval);
952
+ const monthsFree = monthsFreeYearly(pricing);
953
+ const yearlyLabel = monthsFree > 0 ? tf("Yearly, {months} months free", { months: monthsFree }) : t("Yearly");
954
+ const priceNote = [price.note, billingInterval === "year" && monthsFree > 0 ? tf("{months} months free", { months: monthsFree }) : null]
955
+ .filter((part): part is string => !!part)
956
+ .join(" \u00b7 ");
905
957
  return (
906
- <OnboardingModal width={66} height={17}>
958
+ <OnboardingModal width={70} height={28}>
907
959
  <OnboardingHeader
908
960
  active="pro"
909
961
  available={sectionAvailability}
910
962
  onNavigate={goToSection}
911
- onDismiss={() => { void finish(); }}
963
+ onDismiss={skipSetup}
912
964
  dismissing={isFinishing}
913
965
  showDismiss={false}
914
966
  />
915
967
  <OnboardingTitle
916
968
  step={desktop ? undefined : t("GLOOM CLOUD PRO")}
917
- title={planAccess.hasProAccess ? t("Pro is active") : monthlyPrice.price}
918
- titlePrefix={!planAccess.hasProAccess && monthlyPrice.anchor ? (
969
+ title={planAccess.hasProAccess ? t("Pro is active") : price.price}
970
+ titlePrefix={!planAccess.hasProAccess && price.anchor ? (
919
971
  <Text fg={colors.textMuted} attributes={TextAttributes.STRIKETHROUGH}>
920
- {monthlyPrice.anchor}
972
+ {price.anchor}
921
973
  </Text>
922
974
  ) : undefined}
975
+ titleSuffix={!planAccess.hasProAccess && priceNote ? priceNote : undefined}
923
976
  description={planAccess.hasProAccess
924
977
  ? t("This account already has real-time Cloud data.")
925
- : t("7 days free, then the price above. Card required. Cancel anytime.")}
978
+ : t("7 days free. Card required. Cancel anytime.")}
926
979
  />
927
- <Box flexDirection="column" style={desktop ? { marginTop: 14, gap: 8 } : undefined}>
980
+ {!planAccess.hasProAccess ? (
981
+ <Box flexDirection="row" style={desktop ? { marginTop: 12 } : undefined} paddingTop={desktop ? undefined : 1}>
982
+ <SegmentedControl
983
+ options={[
984
+ { label: t("Monthly"), value: "month" },
985
+ { label: yearlyLabel, value: "year" },
986
+ ]}
987
+ value={billingInterval}
988
+ onChange={(value) => setBillingInterval(value === "year" ? "year" : "month")}
989
+ focused={!desktop}
990
+ />
991
+ </Box>
992
+ ) : null}
993
+ {/* Ranked: the data itself first, then what reads it. */}
994
+ <Box flexDirection="column" style={desktop ? { marginTop: ONBOARDING_DESKTOP.afterHeader, gap: 10 } : undefined}>
995
+ <OnboardingFeature
996
+ title={t("Real-time market data")}
997
+ description={t("Free is 15 minutes behind on quotes and 12 hours on news.")}
998
+ />
999
+ <OnboardingFeature
1000
+ title={t("MCP server")}
1001
+ description={t("Claude Code, Codex or Cursor call Gloom's research tools.")}
1002
+ />
1003
+ <OnboardingFeature
1004
+ title={t("Ask Gloom")}
1005
+ description={t("Answers cite filings, calls and news.")}
1006
+ />
928
1007
  <OnboardingFeature
929
- title={t("Worldwide equities and options")}
930
- description={t("Free: 15m delayed. Pro: real-time.")}
1008
+ title={t("Earnings calls")}
1009
+ description={t("Transcripts, summaries, guidance and scores.")}
931
1010
  />
932
1011
  <OnboardingFeature
933
- title={t("News wire")}
934
- description={t("Free: 12h delayed. Pro: real-time.")}
1012
+ title={t("Equity Diagnostic")}
1013
+ description={t("Full report: red and green flags with evidence.")}
935
1014
  />
936
1015
  <OnboardingFeature
937
- title={t("Earnings transcripts and instant search")}
938
- description={t("Read calls. Search transcripts, news and filings. Ask Gloomberb AI coming soon.")}
1016
+ title={t("Search, theses and flow")}
1017
+ description={t("Instant search with alerts, thesis monitoring, options flow, hiring and compensation data.")}
939
1018
  />
940
1019
  </Box>
941
1020
  {persistenceError ? (
@@ -962,16 +1041,12 @@ export function OnboardingWizard({ pluginRegistry, importBrokerPositions, onComp
962
1041
  );
963
1042
  }
964
1043
 
965
- const readyDescription = progress.brokerName
966
- ? tf("Imported {count} positions from {broker}. Your workspace is ready to explore.", {
967
- count: progress.positionsImported ?? 0,
968
- broker: progress.brokerName,
1044
+ const readyDescription = progress.tickerSymbol
1045
+ ? tf("{ticker} is open. {shortcut}, then AP, adds more.", {
1046
+ ticker: progress.tickerSymbol,
1047
+ shortcut: commandBarShortcut,
969
1048
  })
970
- : progress.tickerSymbol
971
- ? tf("{ticker} is in your portfolio, and its research is ready in the workspace.", {
972
- ticker: progress.tickerSymbol,
973
- })
974
- : t("Your local workspace is ready. You can connect Cloud or add a portfolio later.");
1049
+ : t("Your local workspace is ready. You can connect Cloud or add a portfolio later.");
975
1050
 
976
1051
  return (
977
1052
  <OnboardingModal width={66} height={12}>
@@ -979,11 +1054,12 @@ export function OnboardingWizard({ pluginRegistry, importBrokerPositions, onComp
979
1054
  active={progress.accountStatus === "signed-in" ? "pro" : "cloud"}
980
1055
  available={sectionAvailability}
981
1056
  onNavigate={goToSection}
982
- onDismiss={() => { void finish(); }}
1057
+ onDismiss={skipSetup}
983
1058
  dismissing={isFinishing}
1059
+ showDismiss={false}
984
1060
  />
985
1061
  <OnboardingTitle
986
- step={t("READY")}
1062
+ step={desktop ? undefined : t("READY")}
987
1063
  title={t("Your workspace is ready")}
988
1064
  description={readyDescription}
989
1065
  />