gloomberb 0.18.2 → 0.18.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (954) hide show
  1. package/README.md +8 -8
  2. package/README.zh-CN.md +11 -11
  3. package/bin/{gloomberb → gloom} +3 -1
  4. package/package.json +6 -2
  5. package/patches/electrobun@1.18.1.patch +106 -5
  6. package/src/account/checkout-handoff.tsx +225 -0
  7. package/src/account/device-signin-dialog.tsx +2 -2
  8. package/src/account/device-signin.ts +2 -2
  9. package/src/account/upgrade-dialog.tsx +1 -1
  10. package/src/api-client/askg.ts +2 -2
  11. package/src/api-client/auth.ts +2 -2
  12. package/src/api-client/central-bank-rates.ts +6 -0
  13. package/src/api-client/collections.ts +5 -1
  14. package/src/api-client/cot.ts +2 -0
  15. package/src/api-client/crypto-etf-flows.ts +37 -0
  16. package/src/api-client/crypto-markets.ts +60 -0
  17. package/src/api-client/data.ts +99 -5
  18. package/src/api-client/doe.ts +15 -0
  19. package/src/api-client/equity-screener.ts +28 -0
  20. package/src/api-client/exchange-announcements.ts +38 -0
  21. package/src/api-client/fund-facts.ts +39 -0
  22. package/src/api-client/futures-curve.ts +9 -1
  23. package/src/api-client/hiring.ts +301 -0
  24. package/src/api-client/index.ts +24 -5
  25. package/src/api-client/market-discovery.ts +14 -0
  26. package/src/api-client/members.ts +6 -0
  27. package/src/api-client/mna.ts +6 -0
  28. package/src/api-client/paths.ts +18 -1
  29. package/src/api-client/request.ts +26 -7
  30. package/src/api-client/short-side-publications.ts +37 -0
  31. package/src/api-client/socket.ts +64 -4
  32. package/src/api-client/swap-curve.ts +35 -0
  33. package/src/api-client/telemetry.ts +17 -0
  34. package/src/api-client/themes.ts +7 -1
  35. package/src/api-client/types.ts +90 -2
  36. package/src/app/global-shortcuts.ts +1 -16
  37. package/src/app/pane-runtime/plugin-bindings.ts +9 -2
  38. package/src/app/runtime/desktop-deeplink.ts +5 -5
  39. package/src/app/runtime/plugin-bindings.ts +2 -2
  40. package/src/app/runtime/startup.ts +13 -0
  41. package/src/app/runtime/update.ts +28 -8
  42. package/src/app/star-prompt/status-line.tsx +2 -2
  43. package/src/architecture/core-builtin-allowlist.json +5 -2
  44. package/src/architecture/pane-tabs-allowlist.json +65 -0
  45. package/src/architecture/ui-literals-allowlist.json +3 -3
  46. package/src/architecture/ui-tokens-allowlist.json +1 -1
  47. package/src/brokers/broker-portfolio-sync.ts +37 -0
  48. package/src/brokers/directory.ts +11 -0
  49. package/src/brokers/logos.ts +3 -1
  50. package/src/brokers/signed-in/adapter.ts +304 -26
  51. package/src/brokers/signed-in/client.ts +14 -2
  52. package/src/brokers/signed-in/connect.ts +10 -2
  53. package/src/brokers/sync-broker-instance.ts +9 -1
  54. package/src/capabilities/chart-series.ts +22 -6
  55. package/src/cli/bank-section.ts +1 -1
  56. package/src/cli/base-converter.ts +23 -14
  57. package/src/cli/central-bank-events.ts +1 -1
  58. package/src/cli/command-options.ts +59 -4
  59. package/src/cli/commands/api.ts +9 -6
  60. package/src/cli/commands/broker.ts +2 -2
  61. package/src/cli/commands/command-utils.ts +2 -2
  62. package/src/cli/commands/crypto-hints.ts +7 -20
  63. package/src/cli/commands/fred-series.ts +4 -2
  64. package/src/cli/commands/keybindings.ts +2 -2
  65. package/src/cli/commands/market.ts +1189 -296
  66. package/src/cli/commands/news-hints.ts +2 -2
  67. package/src/cli/commands/news-search.ts +59 -6
  68. package/src/cli/commands/options-leaps.ts +41 -26
  69. package/src/cli/commands/overview.ts +121 -48
  70. package/src/cli/commands/plugins.ts +9 -9
  71. package/src/cli/commands/remote.ts +13 -10
  72. package/src/cli/commands/search.ts +64 -44
  73. package/src/cli/commands/system.ts +27 -19
  74. package/src/cli/commands/themes.ts +1 -1
  75. package/src/cli/commands/ticker.ts +272 -70
  76. package/src/cli/context.ts +3 -2
  77. package/src/cli/desktop-pane-shot-view.ts +2 -2
  78. package/src/cli/desktop-pane-shot.ts +1 -1
  79. package/src/cli/earnings-calendar.ts +4 -4
  80. package/src/cli/entry.ts +18 -1
  81. package/src/cli/errors.ts +20 -2
  82. package/src/cli/exit-codes.ts +1 -1
  83. package/src/cli/export-source.ts +10 -4
  84. package/src/cli/freshness.ts +2 -8
  85. package/src/cli/fx-forward.ts +130 -0
  86. package/src/cli/fx-pair.ts +10 -9
  87. package/src/cli/glossary.ts +64 -20
  88. package/src/cli/help.ts +20 -14
  89. package/src/cli/history-export.ts +126 -0
  90. package/src/cli/history-rows.ts +196 -43
  91. package/src/cli/index-roots.ts +5 -45
  92. package/src/cli/index.ts +32 -18
  93. package/src/cli/issuer-membership.ts +103 -0
  94. package/src/cli/known-gaps.ts +118 -25
  95. package/src/cli/listing-arg.ts +315 -43
  96. package/src/cli/name-entries.ts +73 -22
  97. package/src/cli/native-smoke.ts +2 -0
  98. package/src/cli/not-a-ticker.ts +19 -9
  99. package/src/cli/opentui-libc.ts +5 -0
  100. package/src/cli/options.ts +12 -0
  101. package/src/cli/pane-functions/capabilities.ts +77 -20
  102. package/src/cli/pane-functions/catalog.ts +40 -23
  103. package/src/cli/pane-functions/discovery.ts +1 -1
  104. package/src/cli/pane-functions/dom.ts +12 -8
  105. package/src/cli/pane-functions/financial-ratio-shot.ts +2 -2
  106. package/src/cli/pane-functions/freshness.ts +174 -23
  107. package/src/cli/pane-functions/function-help.ts +66 -27
  108. package/src/cli/pane-functions/headless.ts +48 -16
  109. package/src/cli/pane-functions/index.ts +82 -21
  110. package/src/cli/pane-functions/options.ts +22 -2
  111. package/src/cli/pane-functions/report-notices.ts +12 -4
  112. package/src/cli/pane-functions/report.ts +5 -5
  113. package/src/cli/pane-functions/resolver.ts +65 -14
  114. package/src/cli/pane-functions/screenshot-assessment.ts +322 -0
  115. package/src/cli/pane-functions/screenshot-bridge.ts +152 -0
  116. package/src/cli/pane-functions/screenshot-chart-evidence.ts +396 -0
  117. package/src/cli/pane-functions/screenshot-data-evidence.ts +383 -0
  118. package/src/cli/pane-functions/screenshot-evidence.ts +1 -1
  119. package/src/cli/pane-functions/screenshot-payload.ts +453 -0
  120. package/src/cli/pane-functions/screenshot-render.ts +316 -0
  121. package/src/cli/pane-functions/screenshot-types.ts +162 -0
  122. package/src/cli/pane-functions/shot-options.ts +8 -3
  123. package/src/cli/peso-dollar-rates.ts +79 -0
  124. package/src/cli/quote-answer.ts +38 -3
  125. package/src/cli/report-tables.ts +190 -27
  126. package/src/cli/restore-plugins.ts +29 -14
  127. package/src/cli/result.ts +122 -25
  128. package/src/cli/series-search.ts +5 -5
  129. package/src/cli/statement-filings.ts +19 -0
  130. package/src/cli/suffixed-listing-rows.ts +49 -0
  131. package/src/cli/symbol-args.ts +50 -15
  132. package/src/cli/symbol-cells.ts +120 -0
  133. package/src/cli/symbol-list.ts +226 -60
  134. package/src/cli/symbol-rows.ts +131 -25
  135. package/src/cli/ticker-resolution.ts +108 -11
  136. package/src/cli/treasury-yields.ts +5 -5
  137. package/src/cli/types.ts +2 -0
  138. package/src/cli/uncovered-instrument.ts +3 -3
  139. package/src/cli/unknown-command.ts +6 -6
  140. package/src/components/chart/composite/chart-layout.ts +131 -0
  141. package/src/components/chart/composite/composite-chart.tsx +387 -21
  142. package/src/components/chart/composite/drawing-store.ts +26 -6
  143. package/src/components/chart/composite/interactions.ts +9 -3
  144. package/src/components/chart/composite/legend.tsx +75 -3
  145. package/src/components/chart/composite/levels.ts +5 -0
  146. package/src/components/chart/composite/panel-gestures.ts +41 -0
  147. package/src/components/chart/composite/panel-labels.ts +2 -1
  148. package/src/components/chart/composite/panel-surface.tsx +316 -11
  149. package/src/components/chart/composite/price-axis-labels.tsx +27 -3
  150. package/src/components/chart/composite/rasterizer.ts +44 -19
  151. package/src/components/chart/composite/scene.ts +16 -4
  152. package/src/components/chart/composite/text-renderer.ts +48 -21
  153. package/src/components/chart/composite/toolbar.tsx +52 -5
  154. package/src/components/chart/composite/types.ts +19 -0
  155. package/src/components/chart/composite/use-composite-chart-keyboard.ts +120 -13
  156. package/src/components/chart/composite/use-composite-value-scales.ts +44 -0
  157. package/src/components/chart/composite/use-composite-viewport.ts +12 -3
  158. package/src/components/chart/composite/value-scale.ts +149 -0
  159. package/src/components/chart/composite/volume-profile-paint.ts +6 -3
  160. package/src/components/chart/core/pointer.ts +2 -0
  161. package/src/components/chart-table/index.ts +2 -0
  162. package/src/components/chart-table/read.tsx +74 -0
  163. package/src/components/command-bar/commands/collection-list.ts +41 -19
  164. package/src/components/command-bar/commands/collection.ts +9 -3
  165. package/src/components/command-bar/commands/direct/index.ts +1 -1
  166. package/src/components/command-bar/commands/direct/runtime.ts +3 -2
  167. package/src/components/command-bar/pane-templates/items.ts +59 -6
  168. package/src/components/command-bar/pane-templates/workflow.ts +10 -1
  169. package/src/components/command-bar/routes/root/command-items.ts +32 -6
  170. package/src/components/command-bar/routes/root/plugin-install.ts +1 -1
  171. package/src/components/command-bar/routes/root/provider-search.ts +42 -11
  172. package/src/components/command-bar/routes/root/results.ts +18 -4
  173. package/src/components/command-bar/routes/root/runtime.ts +15 -3
  174. package/src/components/command-bar/routes/root/search-providers.ts +25 -2
  175. package/src/components/command-bar/routes/root/selection.ts +6 -1
  176. package/src/components/command-bar/routes/root/shortcut-feedback.ts +4 -1
  177. package/src/components/command-bar/routes/root/shortcuts.ts +30 -3
  178. package/src/components/command-bar/routes/ticker-search/results.ts +73 -4
  179. package/src/components/command-bar/selection-runtime.ts +50 -10
  180. package/src/components/command-bar/surface/index.tsx +24 -2
  181. package/src/components/command-bar/view-model.ts +7 -0
  182. package/src/components/command-bar/workflow/broker.ts +2 -2
  183. package/src/components/command-bar/workflow/collection-actions.ts +46 -7
  184. package/src/components/command-bar/workflow/collection-ticker.ts +32 -4
  185. package/src/components/command-bar/workflow/fields.ts +8 -2
  186. package/src/components/command-bar/workflow/ops.ts +18 -4
  187. package/src/components/command-bar/workflow/portfolio-position.ts +53 -4
  188. package/src/components/command-bar/workflow/submit.ts +3 -2
  189. package/src/components/command-bar/workflow/tickers.ts +5 -1
  190. package/src/components/company-logo.tsx +39 -0
  191. package/src/components/data-table/sections.ts +4 -2
  192. package/src/components/data-table/view.tsx +23 -3
  193. package/src/components/form-modal/confirm.tsx +2 -1
  194. package/src/components/form-modal/request.ts +5 -0
  195. package/src/components/form-modal/routes.ts +4 -1
  196. package/src/components/index.ts +13 -6
  197. package/src/components/layout/detached-pane-shell.tsx +1 -0
  198. package/src/components/layout/floating-pane.tsx +1 -0
  199. package/src/components/layout/header.tsx +234 -60
  200. package/src/components/layout/market-summary.ts +9 -6
  201. package/src/components/layout/pane/capture-status.ts +1 -1
  202. package/src/components/layout/pane/footer/model.ts +11 -5
  203. package/src/components/layout/pane/header.tsx +10 -3
  204. package/src/components/layout/pane/index.tsx +1 -0
  205. package/src/components/layout/pane/pane-tabs.tsx +9 -1
  206. package/src/components/layout/shell/chrome.ts +19 -6
  207. package/src/components/layout/shell/index.tsx +2 -1
  208. package/src/components/layout/shell/pane/layers.tsx +19 -1
  209. package/src/components/layout/status-bar.tsx +2 -2
  210. package/src/components/market-board/index.tsx +11 -3
  211. package/src/components/onboarding/onboarding-wizard.tsx +1 -0
  212. package/src/components/onboarding/portfolio-step/broker-setup-panel.tsx +2 -2
  213. package/src/components/onboarding/wizard-broker-sync.ts +4 -1
  214. package/src/components/pane-settings-dialog/desktop.tsx +20 -7
  215. package/src/components/pane-settings-dialog/tui.tsx +17 -9
  216. package/src/components/pane-settings-dialog/value.ts +8 -1
  217. package/src/components/pane-settings-dialog.tsx +44 -13
  218. package/src/components/sign-in-code-panel.tsx +27 -19
  219. package/src/components/ui/column-grid.tsx +48 -4
  220. package/src/components/ui/country-flag-art.tsx +180 -0
  221. package/src/components/ui/country-flag.tsx +118 -12
  222. package/src/components/ui/data-table/opentui/index.tsx +61 -2
  223. package/src/components/ui/data-table/opentui/model.ts +109 -2
  224. package/src/components/ui/data-table/types.ts +1 -1
  225. package/src/components/ui/display.tsx +5 -1
  226. package/src/components/ui/index.ts +3 -1
  227. package/src/components/ui/logo-mark.tsx +11 -2
  228. package/src/components/ui/query-bar.tsx +1 -1
  229. package/src/components/ui/row-notes.ts +79 -0
  230. package/src/components/ui/stat-grid.tsx +28 -3
  231. package/src/components/ui/status.tsx +3 -1
  232. package/src/core/app-services.ts +4 -0
  233. package/src/core/state/app/layout.ts +4 -4
  234. package/src/data/cached-query.ts +8 -1
  235. package/src/data/config/chart-settings.ts +3 -3
  236. package/src/data/config/home.ts +10 -2
  237. package/src/data/config/layout.ts +4 -1
  238. package/src/data/config/store/node.ts +4 -0
  239. package/src/data/config/store/normalize.ts +13 -3
  240. package/src/data/config/store/portfolio-as-of-column.ts +2 -2
  241. package/src/data/json-storage.ts +2 -0
  242. package/src/data/saved-copies.ts +84 -0
  243. package/src/docs/snapshot.json +65 -32
  244. package/src/i18n/es.ts +51 -12
  245. package/src/i18n/ja.ts +51 -12
  246. package/src/i18n/ko.ts +51 -12
  247. package/src/i18n/zh-cn.ts +51 -12
  248. package/src/i18n/zh-tw.ts +51 -12
  249. package/src/layout/desks.ts +1 -1
  250. package/src/layout/launch-layout.ts +1 -1
  251. package/src/layout/pane-manager/floating-actions.ts +5 -3
  252. package/src/layout/pane-manager/floating.ts +43 -1
  253. package/src/layout/pane-manager/index.ts +2 -0
  254. package/src/layout/selected-ticker.ts +74 -0
  255. package/src/market-data/depositary-pair.ts +251 -0
  256. package/src/market-data/futures-board.ts +1 -1
  257. package/src/market-data/futures-contract.ts +124 -40
  258. package/src/market-data/fx-closes.ts +17 -2
  259. package/src/market-data/hooks.tsx +19 -11
  260. package/src/market-data/market/change-basis.ts +49 -7
  261. package/src/market-data/market/freshness.ts +34 -5
  262. package/src/market-data/market/period-return.ts +163 -0
  263. package/src/market-data/market/trading-sessions.ts +13 -0
  264. package/src/market-data/market/year-to-date.ts +8 -13
  265. package/src/market-data/performance.ts +20 -14
  266. package/src/market-data/perpetual-premium.ts +32 -0
  267. package/src/market-data/published-apac-sessions.ts +2 -1
  268. package/src/market-data/published-futures-sessions.ts +69 -0
  269. package/src/market-data/quotes/contributions.ts +5 -1
  270. package/src/market-data/quotes/freshness.ts +42 -0
  271. package/src/market-data/quotes/intraday-bar.ts +37 -0
  272. package/src/market-data/quotes/regular-session-valuation.ts +13 -8
  273. package/src/market-data/quotes/resolution.ts +4 -2
  274. package/src/market-data/tax-equivalent.ts +1 -1
  275. package/src/market-data/ticker-price-returns.ts +3 -1
  276. package/src/news/aggregator.ts +5 -1
  277. package/src/news/news-model.ts +4 -0
  278. package/src/news/types.ts +11 -0
  279. package/src/notifications/app-notifier.ts +1 -1
  280. package/src/plugins/auto-update.ts +2 -2
  281. package/src/plugins/builtin/account-management/index.tsx +1 -0
  282. package/src/plugins/builtin/account-management/pane.tsx +9 -8
  283. package/src/plugins/builtin/alerts/alert-engine.ts +30 -18
  284. package/src/plugins/builtin/alerts/calendar-events.ts +378 -0
  285. package/src/plugins/builtin/alerts/cli.ts +485 -76
  286. package/src/plugins/builtin/alerts/command.ts +5 -10
  287. package/src/plugins/builtin/alerts/event-rows.ts +9 -5
  288. package/src/plugins/builtin/alerts/events-pane.tsx +71 -56
  289. package/src/plugins/builtin/alerts/events.ts +108 -5
  290. package/src/plugins/builtin/alerts/fired-log.ts +78 -0
  291. package/src/plugins/builtin/alerts/format.ts +2 -1
  292. package/src/plugins/builtin/alerts/headless.ts +100 -39
  293. package/src/plugins/builtin/alerts/history-pane.tsx +105 -62
  294. package/src/plugins/builtin/alerts/history-rows.ts +89 -0
  295. package/src/plugins/builtin/alerts/index.tsx +45 -18
  296. package/src/plugins/builtin/alerts/iv-level.ts +365 -0
  297. package/src/plugins/builtin/alerts/levels.ts +3 -3
  298. package/src/plugins/builtin/alerts/pane.tsx +97 -29
  299. package/src/plugins/builtin/alerts/price.ts +35 -0
  300. package/src/plugins/builtin/alerts/quotes.ts +24 -0
  301. package/src/plugins/builtin/alerts/research-builder.ts +84 -11
  302. package/src/plugins/builtin/alerts/research-rules.ts +77 -3
  303. package/src/plugins/builtin/alerts/scheduled-check.ts +206 -32
  304. package/src/plugins/builtin/alerts/scheduled-sources.ts +26 -3
  305. package/src/plugins/builtin/alerts/scheduled.ts +188 -29
  306. package/src/plugins/builtin/alerts/storage.ts +13 -10
  307. package/src/plugins/builtin/alerts/targets.ts +12 -3
  308. package/src/plugins/builtin/analytics/index.tsx +8 -2
  309. package/src/plugins/builtin/analytics/metrics.ts +1 -1
  310. package/src/plugins/builtin/analytics/risk-book.ts +215 -0
  311. package/src/plugins/builtin/analytics/risk-client.ts +13 -6
  312. package/src/plugins/builtin/analytics/risk-headless.ts +55 -21
  313. package/src/plugins/builtin/analytics/risk-math.ts +6 -3
  314. package/src/plugins/builtin/analytics/risk-model.ts +297 -104
  315. package/src/plugins/builtin/analytics/risk-options.ts +17 -2
  316. package/src/plugins/builtin/analytics/risk-pane.tsx +107 -43
  317. package/src/plugins/builtin/attention/pane.tsx +22 -16
  318. package/src/plugins/builtin/awards/headless.ts +7 -3
  319. package/src/plugins/builtin/awards/model.ts +18 -0
  320. package/src/plugins/builtin/awards/pane.tsx +12 -9
  321. package/src/plugins/builtin/backtest/export.ts +1 -1
  322. package/src/plugins/builtin/backtest/headless.ts +3 -3
  323. package/src/plugins/builtin/backtest/rules.ts +41 -5
  324. package/src/plugins/builtin/broker-manager/add-flow.tsx +12 -7
  325. package/src/plugins/builtin/broker-manager/detail.tsx +47 -19
  326. package/src/plugins/builtin/broker-manager/footer.ts +27 -11
  327. package/src/plugins/builtin/broker-manager/index.tsx +21 -12
  328. package/src/plugins/builtin/broker-manager/keyboard.ts +1 -1
  329. package/src/plugins/builtin/broker-manager/model.ts +12 -2
  330. package/src/plugins/builtin/broker-manager/pane-actions.tsx +183 -57
  331. package/src/plugins/builtin/broker-manager/table.ts +28 -12
  332. package/src/plugins/builtin/broker-trading/account-picker.tsx +2 -1
  333. package/src/plugins/builtin/broker-trading/chart-levels.ts +82 -13
  334. package/src/plugins/builtin/broker-trading/controller.ts +45 -13
  335. package/src/plugins/builtin/broker-trading/dock.tsx +24 -4
  336. package/src/plugins/builtin/broker-trading/headless.ts +2 -1
  337. package/src/plugins/builtin/broker-trading/index.tsx +7 -1
  338. package/src/plugins/builtin/broker-trading/linked-orders.ts +148 -0
  339. package/src/plugins/builtin/broker-trading/order-feed.ts +75 -7
  340. package/src/plugins/builtin/broker-trading/orders.tsx +109 -31
  341. package/src/plugins/builtin/broker-trading/overview-orders.tsx +9 -3
  342. package/src/plugins/builtin/broker-trading/pane-model.ts +30 -2
  343. package/src/plugins/builtin/broker-trading/pane.tsx +115 -26
  344. package/src/plugins/builtin/broker-trading/ticket-parts.tsx +36 -7
  345. package/src/plugins/builtin/broker-trading/ticket.tsx +122 -36
  346. package/src/plugins/builtin/buildout/cells.tsx +4 -0
  347. package/src/plugins/builtin/buildout/detail/index.tsx +5 -1
  348. package/src/plugins/builtin/buildout/detail/ui.tsx +7 -4
  349. package/src/plugins/builtin/buildout/pane/index.tsx +34 -18
  350. package/src/plugins/builtin/buildout/pane/status.tsx +0 -4
  351. package/src/plugins/builtin/builtin-plugin-meta.ts +1 -1
  352. package/src/plugins/builtin/catalysts/client.ts +2 -2
  353. package/src/plugins/builtin/catalysts/detail.tsx +3 -2
  354. package/src/plugins/builtin/catalysts/index.tsx +1 -1
  355. package/src/plugins/builtin/catalysts/model.ts +49 -4
  356. package/src/plugins/builtin/catalysts/pane.tsx +9 -11
  357. package/src/plugins/builtin/central-bank-rates/client.ts +5 -0
  358. package/src/plugins/builtin/central-bank-rates/headless.ts +36 -10
  359. package/src/plugins/builtin/central-bank-rates/model.ts +33 -8
  360. package/src/plugins/builtin/changelog/index.tsx +1 -0
  361. package/src/plugins/builtin/chart-composer/catalog-inventory.ts +1 -0
  362. package/src/plugins/builtin/chart-composer/chart-spec-edit.ts +2 -1
  363. package/src/plugins/builtin/chart-composer/chart-spec.ts +7 -0
  364. package/src/plugins/builtin/chart-composer/cli-options.ts +2 -5
  365. package/src/plugins/builtin/chart-composer/data-catalog-pane.tsx +2 -1
  366. package/src/plugins/builtin/chart-composer/editor/controller.ts +2 -0
  367. package/src/plugins/builtin/chart-composer/editor.tsx +4 -1
  368. package/src/plugins/builtin/chart-composer/headless-schema.ts +28 -26
  369. package/src/plugins/builtin/chart-composer/headless.ts +253 -35
  370. package/src/plugins/builtin/chart-composer/index.tsx +12 -2
  371. package/src/plugins/builtin/chart-composer/leverage-overlay.ts +142 -0
  372. package/src/plugins/builtin/chart-composer/pane.tsx +128 -28
  373. package/src/plugins/builtin/chart-composer/series-catalog.ts +1 -0
  374. package/src/plugins/builtin/chart-composer/series-expression.ts +65 -6
  375. package/src/plugins/builtin/chart-composer/session-history.ts +15 -21
  376. package/src/plugins/builtin/chart-composer/session-range.ts +4 -2
  377. package/src/plugins/builtin/chart-composer/settings.ts +31 -19
  378. package/src/plugins/builtin/chart-composer/use-series-catalog.ts +5 -6
  379. package/src/plugins/builtin/chart-composer/viewport-labels.ts +18 -8
  380. package/src/plugins/builtin/chat/attachments/model.ts +3 -1
  381. package/src/plugins/builtin/chat/content/index.tsx +1 -1
  382. package/src/plugins/builtin/chat/pane-links/open.ts +1 -1
  383. package/src/plugins/builtin/chat/people.ts +1 -1
  384. package/src/plugins/builtin/clinical-trials/client.ts +5 -2
  385. package/src/plugins/builtin/clinical-trials/model.ts +13 -4
  386. package/src/plugins/builtin/clinical-trials/pane.tsx +32 -12
  387. package/src/plugins/builtin/clinical-trials/ticker-sponsor.ts +17 -0
  388. package/src/plugins/builtin/cloud/askg/controller.ts +1 -1
  389. package/src/plugins/builtin/cloud/askg/lock-note.ts +1 -1
  390. package/src/plugins/builtin/cloud/askg/tool-display.ts +1 -1
  391. package/src/plugins/builtin/cloud/auth-commands.ts +3 -3
  392. package/src/plugins/builtin/cloud/team/pane-sections.tsx +105 -47
  393. package/src/plugins/builtin/cloud/team/pane-ui.tsx +42 -4
  394. package/src/plugins/builtin/cloud/team/pane.tsx +204 -64
  395. package/src/plugins/builtin/cloud/thesis/store.ts +45 -22
  396. package/src/plugins/builtin/cloud-tweets/registration.ts +1 -0
  397. package/src/plugins/builtin/commodities-energy/index.tsx +29 -2
  398. package/src/plugins/builtin/commodities-energy/view-state.ts +2 -0
  399. package/src/plugins/builtin/commodity-balances/pane.tsx +14 -8
  400. package/src/plugins/builtin/company-attention/app-rank.tsx +11 -10
  401. package/src/plugins/builtin/company-attention/building-model.ts +222 -0
  402. package/src/plugins/builtin/company-attention/building.tsx +172 -0
  403. package/src/plugins/builtin/company-attention/client.ts +117 -1
  404. package/src/plugins/builtin/company-attention/evidence.ts +16 -3
  405. package/src/plugins/builtin/company-attention/headless.ts +101 -5
  406. package/src/plugins/builtin/company-attention/index.tsx +6 -3
  407. package/src/plugins/builtin/company-attention/model.ts +33 -7
  408. package/src/plugins/builtin/company-attention/moves-model.ts +253 -0
  409. package/src/plugins/builtin/company-attention/moves.tsx +159 -0
  410. package/src/plugins/builtin/company-attention/pane.tsx +89 -31
  411. package/src/plugins/builtin/company-attention/signals-model.ts +229 -0
  412. package/src/plugins/builtin/company-attention/signals.tsx +160 -0
  413. package/src/plugins/builtin/company-kpis/headless.ts +3 -2
  414. package/src/plugins/builtin/company-kpis/model.ts +2 -2
  415. package/src/plugins/builtin/company-kpis/pane.tsx +5 -4
  416. package/src/plugins/builtin/composite-plugins.ts +2 -1
  417. package/src/plugins/builtin/congress-trades/headless.ts +1 -1
  418. package/src/plugins/builtin/connections/index.ts +1 -0
  419. package/src/plugins/builtin/correlation/headless-schema.ts +3 -2
  420. package/src/plugins/builtin/correlation/headless.ts +7 -4
  421. package/src/plugins/builtin/correlation/relationship/model.ts +1 -0
  422. package/src/plugins/builtin/correlation/settings.ts +1 -0
  423. package/src/plugins/builtin/cot/headless.ts +28 -6
  424. package/src/plugins/builtin/cot/model.ts +12 -0
  425. package/src/plugins/builtin/cot/pane.tsx +7 -5
  426. package/src/plugins/builtin/cpi/headless.ts +5 -1
  427. package/src/plugins/builtin/cpi/pane.tsx +11 -9
  428. package/src/plugins/builtin/credit-boards/model.ts +2 -0
  429. package/src/plugins/builtin/credit-documents/headless.ts +1 -1
  430. package/src/plugins/builtin/credit-documents/pane.tsx +8 -7
  431. package/src/plugins/builtin/crypto-board/client.ts +86 -0
  432. package/src/plugins/builtin/crypto-board/defi-view.tsx +218 -0
  433. package/src/plugins/builtin/crypto-board/defi.ts +239 -0
  434. package/src/plugins/builtin/crypto-board/headless.ts +117 -6
  435. package/src/plugins/builtin/crypto-board/index.tsx +8 -3
  436. package/src/plugins/builtin/crypto-board/model.ts +40 -8
  437. package/src/plugins/builtin/crypto-board/pane.tsx +55 -21
  438. package/src/plugins/builtin/crypto-board/series.ts +19 -1
  439. package/src/plugins/builtin/crypto-etf-flows/client.ts +60 -0
  440. package/src/plugins/builtin/crypto-etf-flows/headless.ts +132 -0
  441. package/src/plugins/builtin/crypto-etf-flows/index.tsx +44 -0
  442. package/src/plugins/builtin/crypto-etf-flows/model.ts +121 -0
  443. package/src/plugins/builtin/crypto-etf-flows/pane.tsx +193 -0
  444. package/src/plugins/builtin/debt-maturities/pane.tsx +4 -3
  445. package/src/plugins/builtin/debug/index.tsx +1 -0
  446. package/src/plugins/builtin/dividend-yield/index.tsx +1 -1
  447. package/src/plugins/builtin/docs/index.tsx +1 -1
  448. package/src/plugins/builtin/docs/pane.tsx +2 -2
  449. package/src/plugins/builtin/docs/targets.ts +1 -1
  450. package/src/plugins/builtin/doe/client.ts +5 -1
  451. package/src/plugins/builtin/doe/headless.ts +12 -6
  452. package/src/plugins/builtin/doe/model.ts +43 -6
  453. package/src/plugins/builtin/doe/pane.tsx +19 -12
  454. package/src/plugins/builtin/earnings/board-model.ts +13 -6
  455. package/src/plugins/builtin/earnings/board-table.ts +4 -1
  456. package/src/plugins/builtin/earnings/board.tsx +253 -50
  457. package/src/plugins/builtin/earnings/calendar-model.ts +188 -0
  458. package/src/plugins/builtin/earnings/calendar.tsx +338 -0
  459. package/src/plugins/builtin/earnings/client.ts +4 -3
  460. package/src/plugins/builtin/earnings/headless.ts +53 -15
  461. package/src/plugins/builtin/earnings/history-model.ts +53 -36
  462. package/src/plugins/builtin/earnings/index.tsx +15 -22
  463. package/src/plugins/builtin/earnings/model.ts +17 -12
  464. package/src/plugins/builtin/earnings/scope.ts +89 -0
  465. package/src/plugins/builtin/earnings-calls/calendar.tsx +310 -0
  466. package/src/plugins/builtin/earnings-calls/data.ts +146 -2
  467. package/src/plugins/builtin/earnings-calls/headless.ts +151 -9
  468. package/src/plugins/builtin/earnings-calls/index.tsx +3 -3
  469. package/src/plugins/builtin/earnings-calls/lock-note.ts +1 -1
  470. package/src/plugins/builtin/earnings-calls/pane.tsx +149 -31
  471. package/src/plugins/builtin/earnings-calls/upcoming.ts +195 -0
  472. package/src/plugins/builtin/earnings-ripple/pane.tsx +10 -5
  473. package/src/plugins/builtin/econ/calendar-model.ts +132 -20
  474. package/src/plugins/builtin/econ/detail-view.tsx +48 -10
  475. package/src/plugins/builtin/econ/fred-catalog.ts +23 -6
  476. package/src/plugins/builtin/econ/fred-series-map.ts +4 -0
  477. package/src/plugins/builtin/econ/index.tsx +112 -25
  478. package/src/plugins/builtin/econ/print-watch.ts +2 -1
  479. package/src/plugins/builtin/econ/types.ts +32 -1
  480. package/src/plugins/builtin/econ-statistics/client.ts +16 -3
  481. package/src/plugins/builtin/econ-statistics/defs.ts +4 -0
  482. package/src/plugins/builtin/econ-statistics/detail.tsx +2 -2
  483. package/src/plugins/builtin/econ-statistics/headless.ts +13 -2
  484. package/src/plugins/builtin/econ-statistics/index.tsx +3 -3
  485. package/src/plugins/builtin/econ-statistics/pane.tsx +2 -1
  486. package/src/plugins/builtin/econ-statistics/stats.ts +103 -0
  487. package/src/plugins/builtin/econ-statistics/view.ts +16 -1
  488. package/src/plugins/builtin/equity-screener/client.ts +21 -3
  489. package/src/plugins/builtin/equity-screener/headless.ts +77 -5
  490. package/src/plugins/builtin/equity-screener/live.ts +1 -1
  491. package/src/plugins/builtin/equity-screener/model.ts +34 -0
  492. package/src/plugins/builtin/equity-screener/pane.tsx +148 -106
  493. package/src/plugins/builtin/equity-screener/screen-check.ts +90 -0
  494. package/src/plugins/builtin/equity-screener/ticker-check.tsx +148 -0
  495. package/src/plugins/builtin/estimate-revisions/headless.ts +3 -1
  496. package/src/plugins/builtin/estimate-revisions/lock-note.ts +3 -3
  497. package/src/plugins/builtin/estimate-revisions/model.ts +8 -10
  498. package/src/plugins/builtin/exposure/headless.ts +51 -6
  499. package/src/plugins/builtin/exposure/index.tsx +28 -2
  500. package/src/plugins/builtin/exposure/model.ts +7 -0
  501. package/src/plugins/builtin/exposure/pane.tsx +16 -10
  502. package/src/plugins/builtin/fear-greed/index.tsx +1 -1
  503. package/src/plugins/builtin/filing-events/index.tsx +1 -1
  504. package/src/plugins/builtin/futures/model.ts +10 -9
  505. package/src/plugins/builtin/futures/returns.ts +8 -36
  506. package/src/plugins/builtin/futures/table.tsx +1 -1
  507. package/src/plugins/builtin/futures-curve/client.ts +40 -9
  508. package/src/plugins/builtin/futures-curve/headless.ts +39 -17
  509. package/src/plugins/builtin/futures-curve/model.ts +258 -69
  510. package/src/plugins/builtin/futures-curve/pane.tsx +46 -17
  511. package/src/plugins/builtin/fx-matrix/client.ts +15 -8
  512. package/src/plugins/builtin/fx-matrix/headless.ts +32 -14
  513. package/src/plugins/builtin/fx-matrix/index.tsx +13 -11
  514. package/src/plugins/builtin/fx-matrix/live-legs.ts +22 -0
  515. package/src/plugins/builtin/fx-matrix/settings.ts +2 -1
  516. package/src/plugins/builtin/gpu/board.tsx +4 -1
  517. package/src/plugins/builtin/gpu/changes.tsx +10 -10
  518. package/src/plugins/builtin/gpu/equities.tsx +4 -1
  519. package/src/plugins/builtin/gpu/headless.ts +9 -4
  520. package/src/plugins/builtin/gpu/history.tsx +4 -2
  521. package/src/plugins/builtin/gpu/pane.tsx +5 -3
  522. package/src/plugins/builtin/help/index.tsx +13 -3
  523. package/src/plugins/builtin/holders/beneficial-model.ts +8 -11
  524. package/src/plugins/builtin/holders/beneficial-report.ts +6 -5
  525. package/src/plugins/builtin/holders/beneficial-view.tsx +7 -3
  526. package/src/plugins/builtin/holders/client.ts +15 -2
  527. package/src/plugins/builtin/holders/format.ts +28 -17
  528. package/src/plugins/builtin/holders/headless.ts +48 -8
  529. package/src/plugins/builtin/holders/index-holders.ts +264 -0
  530. package/src/plugins/builtin/holders/pane.tsx +79 -15
  531. package/src/plugins/builtin/holders/report-rows.ts +35 -7
  532. package/src/plugins/builtin/holders/table-model.ts +2 -1
  533. package/src/plugins/builtin/holders/thirteenf-match.ts +3 -1
  534. package/src/plugins/builtin/holders/treemap.tsx +2 -2
  535. package/src/plugins/builtin/insider/base-values.ts +11 -7
  536. package/src/plugins/builtin/insider/client.ts +3 -0
  537. package/src/plugins/builtin/insider/headless.ts +20 -7
  538. package/src/plugins/builtin/insider/index.tsx +17 -8
  539. package/src/plugins/builtin/insider/issuer.ts +34 -4
  540. package/src/plugins/builtin/insider/signals-client.ts +3 -3
  541. package/src/plugins/builtin/insider/signals.tsx +1 -1
  542. package/src/plugins/builtin/insider/table-model.ts +35 -13
  543. package/src/plugins/builtin/insider/table.tsx +5 -2
  544. package/src/plugins/builtin/ipo-calendar/pane.tsx +7 -4
  545. package/src/plugins/builtin/iv-history/client.ts +20 -0
  546. package/src/plugins/builtin/iv-history/events.ts +145 -0
  547. package/src/plugins/builtin/iv-history/format.ts +3 -0
  548. package/src/plugins/builtin/iv-history/headless.ts +91 -7
  549. package/src/plugins/builtin/iv-history/index.tsx +1 -1
  550. package/src/plugins/builtin/iv-history/model.ts +13 -4
  551. package/src/plugins/builtin/iv-history/series.ts +3 -1
  552. package/src/plugins/builtin/jobs/lock-note.ts +1 -1
  553. package/src/plugins/builtin/jobs/model.ts +4 -15
  554. package/src/plugins/builtin/jobs/pane.tsx +7 -5
  555. package/src/plugins/builtin/jobs/share-bars.tsx +11 -5
  556. package/src/plugins/builtin/jodi/pane.tsx +14 -8
  557. package/src/plugins/builtin/layout-manager/index.tsx +1 -0
  558. package/src/plugins/builtin/macro-day/headless.ts +20 -7
  559. package/src/plugins/builtin/macro-day/index.tsx +3 -2
  560. package/src/plugins/builtin/macro-day/model.ts +29 -8
  561. package/src/plugins/builtin/macro-day/pane.tsx +46 -10
  562. package/src/plugins/builtin/macro-day/releases.ts +55 -13
  563. package/src/plugins/builtin/market-heatmap/data.ts +9 -2
  564. package/src/plugins/builtin/market-heatmap/evidence.ts +1 -1
  565. package/src/plugins/builtin/market-heatmap/headless.ts +9 -6
  566. package/src/plugins/builtin/market-heatmap/index.tsx +3 -3
  567. package/src/plugins/builtin/market-heatmap/model.ts +10 -7
  568. package/src/plugins/builtin/market-movers/client.ts +36 -21
  569. package/src/plugins/builtin/market-movers/headless.ts +8 -2
  570. package/src/plugins/builtin/market-movers/index.tsx +16 -10
  571. package/src/plugins/builtin/market-movers/screener.ts +33 -11
  572. package/src/plugins/builtin/market-movers/session-body.tsx +4 -2
  573. package/src/plugins/builtin/market-movers/session-table.ts +4 -2
  574. package/src/plugins/builtin/market-movers/table.ts +4 -1
  575. package/src/plugins/builtin/market-valuation/headless.ts +2 -0
  576. package/src/plugins/builtin/market-valuation/view.ts +5 -0
  577. package/src/plugins/builtin/members/headless.ts +6 -5
  578. package/src/plugins/builtin/members/pane.tsx +11 -4
  579. package/src/plugins/builtin/mna/client.ts +1 -0
  580. package/src/plugins/builtin/mna/detail.tsx +20 -32
  581. package/src/plugins/builtin/mna/distress/detail.tsx +16 -4
  582. package/src/plugins/builtin/mna/distress/model.ts +3 -2
  583. package/src/plugins/builtin/mna/distress/pane.tsx +7 -4
  584. package/src/plugins/builtin/mna/headless.ts +6 -13
  585. package/src/plugins/builtin/mna/model.ts +93 -15
  586. package/src/plugins/builtin/mna/pane.tsx +5 -4
  587. package/src/plugins/builtin/news/headless.ts +12 -6
  588. package/src/plugins/builtin/news/index.tsx +10 -1
  589. package/src/plugins/builtin/news/wire/index.tsx +3 -2
  590. package/src/plugins/builtin/news/wire/news/command-bar-search.ts +26 -10
  591. package/src/plugins/builtin/news/wire/news/query-presets.ts +6 -2
  592. package/src/plugins/builtin/news/wire/rss/cli.ts +3 -3
  593. package/src/plugins/builtin/notes/cli.ts +50 -15
  594. package/src/plugins/builtin/notes/export.ts +17 -6
  595. package/src/plugins/builtin/notes/files.ts +16 -5
  596. package/src/plugins/builtin/openfda/pane.tsx +1 -1
  597. package/src/plugins/builtin/options/carry.ts +2 -2
  598. package/src/plugins/builtin/options/enrichment-model.ts +10 -9
  599. package/src/plugins/builtin/options/index.tsx +1 -1
  600. package/src/plugins/builtin/options/model-spot.ts +70 -4
  601. package/src/plugins/builtin/options/view.tsx +51 -23
  602. package/src/plugins/builtin/options-calculator/headless.ts +46 -7
  603. package/src/plugins/builtin/options-calculator/pane.tsx +3 -2
  604. package/src/plugins/builtin/options-positioning/headless.ts +11 -3
  605. package/src/plugins/builtin/options-positioning/model.ts +24 -0
  606. package/src/plugins/builtin/options-positioning/pane.tsx +10 -12
  607. package/src/plugins/builtin/options-scenario/client.ts +142 -29
  608. package/src/plugins/builtin/options-scenario/collar.ts +8 -6
  609. package/src/plugins/builtin/options-scenario/csp-screen-headless.ts +127 -0
  610. package/src/plugins/builtin/options-scenario/csp-screen-pane.tsx +165 -0
  611. package/src/plugins/builtin/options-scenario/csp-screen.ts +258 -0
  612. package/src/plugins/builtin/options-scenario/csp.ts +101 -21
  613. package/src/plugins/builtin/options-scenario/headless.ts +49 -21
  614. package/src/plugins/builtin/options-scenario/hedge.ts +20 -14
  615. package/src/plugins/builtin/options-scenario/index.tsx +28 -3
  616. package/src/plugins/builtin/options-scenario/model.ts +13 -0
  617. package/src/plugins/builtin/options-scenario/pane.tsx +22 -10
  618. package/src/plugins/builtin/perps/equity-row.tsx +11 -3
  619. package/src/plugins/builtin/perps/freshness.ts +8 -5
  620. package/src/plugins/builtin/perps/headless.ts +3 -1
  621. package/src/plugins/builtin/perps/list-perpetuals.ts +25 -4
  622. package/src/plugins/builtin/perps/live-rows.ts +161 -0
  623. package/src/plugins/builtin/perps/markets-section.tsx +154 -0
  624. package/src/plugins/builtin/perps/pane.tsx +36 -17
  625. package/src/plugins/builtin/perps/venue-markets.ts +96 -0
  626. package/src/plugins/builtin/plugin-marketplace/index.tsx +2 -1
  627. package/src/plugins/builtin/plugin-marketplace/pane.tsx +145 -60
  628. package/src/plugins/builtin/portfolio-list/cli/bulk-symbols.ts +78 -27
  629. package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +158 -141
  630. package/src/plugins/builtin/portfolio-list/cli/render.ts +49 -20
  631. package/src/plugins/builtin/portfolio-list/cli/shared.ts +3 -3
  632. package/src/plugins/builtin/portfolio-list/cli/watchlist-command.ts +29 -24
  633. package/src/plugins/builtin/portfolio-list/headless.ts +6 -3
  634. package/src/plugins/builtin/portfolio-list/income.ts +13 -2
  635. package/src/plugins/builtin/portfolio-list/index.tsx +9 -2
  636. package/src/plugins/builtin/portfolio-list/pane/index.tsx +21 -8
  637. package/src/plugins/builtin/portfolio-list/pane/purchase-date-fx.ts +46 -0
  638. package/src/plugins/builtin/portfolio-list/summary/live-accounts.ts +16 -9
  639. package/src/plugins/builtin/portfolio-list/summary/totals.ts +2 -15
  640. package/src/plugins/builtin/power/client.ts +6 -3
  641. package/src/plugins/builtin/power/evidence.ts +22 -7
  642. package/src/plugins/builtin/power/gas.tsx +5 -1
  643. package/src/plugins/builtin/power/pane.tsx +44 -32
  644. package/src/plugins/builtin/power/prices.tsx +10 -3
  645. package/src/plugins/builtin/research/analyst-headless.ts +25 -8
  646. package/src/plugins/builtin/research/analyst-model.ts +68 -3
  647. package/src/plugins/builtin/research/corporate-actions-pane.tsx +63 -14
  648. package/src/plugins/builtin/research/event-model.ts +3 -1
  649. package/src/plugins/builtin/research/event-sources.ts +12 -4
  650. package/src/plugins/builtin/research/index.tsx +2 -1
  651. package/src/plugins/builtin/research/relative-valuation-basis.ts +58 -0
  652. package/src/plugins/builtin/research/relative-valuation-columns.ts +31 -2
  653. package/src/plugins/builtin/research/relative-valuation-currency.ts +12 -5
  654. package/src/plugins/builtin/research/relative-valuation-headless.ts +84 -26
  655. package/src/plugins/builtin/research/relative-valuation-model.ts +88 -19
  656. package/src/plugins/builtin/research/relative-valuation-pane.tsx +76 -9
  657. package/src/plugins/builtin/research/relative-valuation-peers.ts +1 -1
  658. package/src/plugins/builtin/reverse-dcf/client.ts +2 -1
  659. package/src/plugins/builtin/reverse-dcf/model.ts +10 -5
  660. package/src/plugins/builtin/risk-factors/index.tsx +2 -2
  661. package/src/plugins/builtin/scanner/lock-note.ts +1 -1
  662. package/src/plugins/builtin/seasonality/client.ts +2 -1
  663. package/src/plugins/builtin/sec/forms.ts +13 -0
  664. package/src/plugins/builtin/sec/fund-abroad.ts +32 -0
  665. package/src/plugins/builtin/sec/fund-facts.ts +68 -8
  666. package/src/plugins/builtin/sec/headless.ts +85 -8
  667. package/src/plugins/builtin/sec/index.tsx +58 -12
  668. package/src/plugins/builtin/sectors/client.ts +6 -4
  669. package/src/plugins/builtin/sectors/sector-model.ts +11 -15
  670. package/src/plugins/builtin/series-inventory.ts +2 -0
  671. package/src/plugins/builtin/shared/broker-reconnect.ts +107 -22
  672. package/src/plugins/builtin/shared/cloud-resource.ts +15 -2
  673. package/src/plugins/builtin/shared/cloud-upgrade.ts +34 -6
  674. package/src/plugins/builtin/shared/earnings-calendar.ts +375 -0
  675. package/src/plugins/builtin/{earnings/estimate-basis.ts → shared/earnings-estimate-basis.ts} +1 -1
  676. package/src/plugins/builtin/shared/earnings-report.ts +3 -3
  677. package/src/plugins/builtin/shared/fx-rate-freshness.ts +23 -1
  678. package/src/plugins/builtin/shared/job-posting.ts +129 -0
  679. package/src/plugins/builtin/shared/pro-lock-note.ts +3 -3
  680. package/src/plugins/builtin/shared/report-freshness.ts +3 -0
  681. package/src/plugins/builtin/shared/research-trading.tsx +23 -0
  682. package/src/plugins/builtin/shared/series-cache.ts +2 -0
  683. package/src/plugins/builtin/shared/series-list-detail.tsx +3 -1
  684. package/src/plugins/builtin/shared/ticker-surface.ts +2 -1
  685. package/src/plugins/builtin/shared/volatility/options.ts +2 -1
  686. package/src/plugins/builtin/short-interest/client.ts +2 -0
  687. package/src/plugins/builtin/short-interest/headless.ts +41 -12
  688. package/src/plugins/builtin/short-interest/index.tsx +23 -1
  689. package/src/plugins/builtin/short-interest/model.ts +70 -19
  690. package/src/plugins/builtin/short-interest/pane.tsx +19 -2
  691. package/src/plugins/builtin/short-interest/publications-client.ts +82 -0
  692. package/src/plugins/builtin/short-interest/publications-headless.ts +29 -0
  693. package/src/plugins/builtin/short-interest/publications-model.ts +50 -0
  694. package/src/plugins/builtin/short-interest/publications-pane.tsx +66 -0
  695. package/src/plugins/builtin/short-interest/schedule.ts +35 -2
  696. package/src/plugins/builtin/short-interest/surface.tsx +11 -4
  697. package/src/plugins/builtin/short-interest/types.ts +9 -0
  698. package/src/plugins/builtin/short-interest/watch-client.ts +14 -8
  699. package/src/plugins/builtin/short-interest/watch-model.ts +12 -25
  700. package/src/plugins/builtin/short-interest/watch-pane.tsx +5 -1
  701. package/src/plugins/builtin/social-mentions/client.ts +2 -1
  702. package/src/plugins/builtin/supply-chain/flow.tsx +33 -9
  703. package/src/plugins/builtin/supply-chain/model.ts +51 -3
  704. package/src/plugins/builtin/supply-chain/pane.tsx +78 -39
  705. package/src/plugins/builtin/supply-chain/row-evidence.tsx +1 -1
  706. package/src/plugins/builtin/themes/headless.ts +8 -5
  707. package/src/plugins/builtin/themes/model.ts +14 -4
  708. package/src/plugins/builtin/themes/pane.tsx +24 -5
  709. package/src/plugins/builtin/thirteenf/headless.ts +5 -5
  710. package/src/plugins/builtin/thirteenf/signals.ts +3 -1
  711. package/src/plugins/builtin/ticker-detail/adr-pair/headless.ts +123 -0
  712. package/src/plugins/builtin/ticker-detail/adr-pair/model.ts +132 -0
  713. package/src/plugins/builtin/ticker-detail/adr-pair/tab.tsx +87 -0
  714. package/src/plugins/builtin/ticker-detail/data-panes/historical-prices.tsx +40 -26
  715. package/src/plugins/builtin/ticker-detail/data-panes/history-bars.ts +8 -4
  716. package/src/plugins/builtin/ticker-detail/data-panes/returns-history.ts +67 -3
  717. package/src/plugins/builtin/ticker-detail/data-panes/returns-model.ts +112 -5
  718. package/src/plugins/builtin/ticker-detail/data-panes/returns-pane.tsx +17 -2
  719. package/src/plugins/builtin/ticker-detail/financials/aggregation.ts +21 -7
  720. package/src/plugins/builtin/ticker-detail/financials/model.ts +36 -1
  721. package/src/plugins/builtin/ticker-detail/financials/offerings.ts +56 -0
  722. package/src/plugins/builtin/ticker-detail/financials/ratios.ts +62 -13
  723. package/src/plugins/builtin/ticker-detail/financials/tab.tsx +30 -4
  724. package/src/plugins/builtin/ticker-detail/headless-schema.ts +14 -2
  725. package/src/plugins/builtin/ticker-detail/headless.ts +148 -35
  726. package/src/plugins/builtin/ticker-detail/index.tsx +37 -5
  727. package/src/plugins/builtin/ticker-detail/overview/model.ts +65 -10
  728. package/src/plugins/builtin/ticker-detail/overview/pane.tsx +9 -1
  729. package/src/plugins/builtin/ticker-detail/overview-tab.tsx +68 -11
  730. package/src/plugins/builtin/ticker-detail/pane.tsx +11 -0
  731. package/src/plugins/builtin/ticker-detail/quote-footer.ts +8 -3
  732. package/src/plugins/builtin/ticker-detail/research-tabs.ts +11 -0
  733. package/src/plugins/builtin/vol-surface/client.ts +28 -7
  734. package/src/plugins/builtin/vol-surface/headless.ts +43 -15
  735. package/src/plugins/builtin/vol-surface/model.ts +34 -12
  736. package/src/plugins/builtin/vol-surface/pane.tsx +33 -13
  737. package/src/plugins/builtin/vol-surface/stored.ts +34 -3
  738. package/src/plugins/builtin/vol-surface/tables.ts +14 -0
  739. package/src/plugins/builtin/volatility/model.ts +5 -10
  740. package/src/plugins/builtin/world-venue-map/basemap-layer.tsx +4 -3
  741. package/src/plugins/builtin/world-venue-map/basemap.ts +3 -1
  742. package/src/plugins/builtin/world-venue-map/chokepoint-chart.ts +40 -0
  743. package/src/plugins/builtin/world-venue-map/evidence.ts +1 -1
  744. package/src/plugins/builtin/world-venue-map/geo-series.ts +90 -11
  745. package/src/plugins/builtin/world-venue-map/headless.ts +1 -1
  746. package/src/plugins/builtin/world-venue-map/index.ts +3 -26
  747. package/src/plugins/builtin/world-venue-map/layers.ts +1 -1
  748. package/src/plugins/builtin/world-venue-map/map.tsx +2 -1
  749. package/src/plugins/builtin/world-venue-map/pane.tsx +4 -2
  750. package/src/plugins/builtin/world-venue-map/venue-header.tsx +15 -4
  751. package/src/plugins/builtin/yield-curve/client.ts +25 -0
  752. package/src/plugins/builtin/yield-curve/curves.ts +7 -4
  753. package/src/plugins/builtin/yield-curve/headless.ts +38 -4
  754. package/src/plugins/builtin/yield-curve/history.ts +4 -3
  755. package/src/plugins/builtin/yield-curve/index.tsx +12 -6
  756. package/src/plugins/builtin/yield-curve/swaps-model.ts +93 -0
  757. package/src/plugins/builtin/yield-curve/swaps.tsx +99 -0
  758. package/src/plugins/bundle.ts +1 -1
  759. package/src/plugins/catalog-browser.ts +2 -1
  760. package/src/plugins/compat.ts +3 -3
  761. package/src/plugins/dependencies.ts +75 -14
  762. package/src/plugins/extracted-plugins.ts +132 -34
  763. package/src/plugins/host-link.ts +149 -34
  764. package/src/plugins/installer.ts +35 -10
  765. package/src/plugins/loader.ts +206 -38
  766. package/src/plugins/manager-node.ts +2 -2
  767. package/src/plugins/marketplace/deactivation.ts +22 -0
  768. package/src/plugins/marketplace/model.ts +2 -2
  769. package/src/plugins/marketplace/packs.ts +1 -1
  770. package/src/plugins/ownership.ts +1 -1
  771. package/src/plugins/peer-retry.ts +155 -0
  772. package/src/plugins/registry/contributions.ts +3 -1
  773. package/src/plugins/registry/index.ts +4 -3
  774. package/src/plugins/registry/plugin-state.ts +3 -0
  775. package/src/plugins/seed-notice.ts +20 -0
  776. package/src/plugins/shortcut-argument.ts +39 -0
  777. package/src/portfolio/allocation.ts +1 -1
  778. package/src/portfolio/collection-name.ts +31 -0
  779. package/src/portfolio/column-values.ts +10 -8
  780. package/src/portfolio/cost-fx.ts +296 -19
  781. package/src/portfolio/manual-lots.ts +75 -0
  782. package/src/portfolio/mutations.ts +60 -22
  783. package/src/portfolio/suffixed-listings.ts +209 -0
  784. package/src/portfolio/totals-currency.ts +24 -0
  785. package/src/public/__snapshots__/public-api.test.ts.snap +14 -0
  786. package/src/public/time-series.ts +11 -8
  787. package/src/remote/schema.ts +1 -1
  788. package/src/renderers/browser/config-host.ts +3 -0
  789. package/src/renderers/browser/main.tsx +23 -3
  790. package/src/renderers/dom/boot-frame-page.ts +187 -0
  791. package/src/renderers/dom/boot-frame.ts +237 -0
  792. package/src/renderers/dom/build-assets.ts +46 -8
  793. package/src/renderers/dom/desktop/controls.tsx +1 -1
  794. package/src/renderers/dom/desktop/query-bar.tsx +2 -0
  795. package/src/renderers/dom/dom-ui-host.tsx +4 -29
  796. package/src/renderers/dom/host/ascii-text.ts +16 -2
  797. package/src/renderers/dom/host/box.tsx +43 -2
  798. package/src/renderers/dom/host/chart-surface.tsx +2 -0
  799. package/src/renderers/dom/host/hls.chunk.ts +3 -0
  800. package/src/renderers/dom/host/image-surface.tsx +49 -0
  801. package/src/renderers/dom/host/media-surface.tsx +24 -18
  802. package/src/renderers/dom/host/mouse.ts +30 -0
  803. package/src/renderers/dom/host/size-observer.ts +1 -1
  804. package/src/renderers/dom/host/style.ts +1 -1
  805. package/src/renderers/dom/host/tabs.tsx +16 -5
  806. package/src/renderers/dom/host/top-surface.ts +127 -0
  807. package/src/renderers/dom/styles.css +115 -0
  808. package/src/renderers/dom/test-utils.tsx +2 -1
  809. package/src/renderers/electrobun/bun/application-menu/index.ts +3 -3
  810. package/src/renderers/electrobun/bun/core-capabilities.ts +9 -1
  811. package/src/renderers/electrobun/bun/desktop/backend-requests.ts +3 -0
  812. package/src/renderers/electrobun/bun/desktop/backend.ts +56 -3
  813. package/src/renderers/electrobun/bun/desktop/detached-windows.ts +1 -1
  814. package/src/renderers/electrobun/bun/desktop/host-requests.ts +9 -3
  815. package/src/renderers/electrobun/bun/desktop/initialization.ts +81 -18
  816. package/src/renderers/electrobun/bun/desktop/update.ts +210 -30
  817. package/src/renderers/electrobun/bun/external-plugins.ts +29 -7
  818. package/src/renderers/electrobun/bun/index.ts +11 -1
  819. package/src/renderers/electrobun/bun/window/boot-frame.ts +67 -0
  820. package/src/renderers/electrobun/bun/window/create.ts +4 -1
  821. package/src/renderers/electrobun/shared/boot-frame.ts +7 -0
  822. package/src/renderers/electrobun/shared/protocol.ts +6 -1
  823. package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +1 -1
  824. package/src/renderers/electrobun/view/config-host.ts +3 -0
  825. package/src/renderers/electrobun/view/fatal-screen.tsx +1 -1
  826. package/src/renderers/electrobun/view/main.tsx +30 -4
  827. package/src/renderers/electrobun/view/news-source.ts +9 -7
  828. package/src/renderers/electrobun/view/remote/asset-data-client.ts +9 -2
  829. package/src/renderers/electrobun/view/ui-host.tsx +1 -1
  830. package/src/renderers/opentui/browser-open.ts +88 -0
  831. package/src/renderers/opentui/host.tsx +5 -14
  832. package/src/renderers/opentui/image/loader.ts +3 -2
  833. package/src/renderers/opentui/native-smoke.ts +10 -1
  834. package/src/renderers/opentui/pane-image/index.ts +2 -1
  835. package/src/renderers/opentui/render-lib.ts +253 -0
  836. package/src/renderers/opentui/render-timing-smoke.ts +1 -1
  837. package/src/renderers/opentui/start.tsx +8 -1
  838. package/src/renderers/share/layout-view.tsx +2 -2
  839. package/src/renderers/share/main.tsx +4 -4
  840. package/src/renderers/share/view.tsx +1 -1
  841. package/src/series/resolve.ts +22 -6
  842. package/src/series/standalone.ts +30 -2
  843. package/src/series/types.ts +8 -1
  844. package/src/shares/api.ts +4 -1
  845. package/src/shares/pane.ts +1 -1
  846. package/src/sources/gloomberb-cloud/fred-series.ts +46 -1
  847. package/src/sources/gloomberb-cloud/index.ts +39 -16
  848. package/src/sources/gloomberb-cloud/news.ts +39 -0
  849. package/src/sources/gloomberb-cloud/normalizers.ts +14 -1
  850. package/src/sources/gloomberb-cloud/perpetuals.ts +49 -1
  851. package/src/sources/listing-symbols.ts +37 -0
  852. package/src/sources/provider-errors.ts +16 -2
  853. package/src/sources/provider-router/financial-routes.ts +21 -3
  854. package/src/sources/provider-router/financials.ts +15 -2
  855. package/src/sources/provider-router/history.ts +30 -8
  856. package/src/sources/provider-router/index.ts +16 -0
  857. package/src/sources/provider-router/primary.ts +1 -1
  858. package/src/state/app/bootstrap.ts +23 -0
  859. package/src/state/hooks/inline-tickers.ts +30 -5
  860. package/src/sync/controller.ts +1 -1
  861. package/src/sync/core-contributors.ts +46 -14
  862. package/src/team/collections-sync.ts +2 -1
  863. package/src/team/collections.ts +178 -17
  864. package/src/telemetry/crash-reports.ts +21 -4
  865. package/src/telemetry/update-failures-node.ts +59 -0
  866. package/src/telemetry/update-failures.ts +307 -0
  867. package/src/test-support/builtin-panes.ts +1 -1
  868. package/src/theme/colors.ts +3 -30
  869. package/src/theme/ui-tokens.ts +37 -1
  870. package/src/tickers/company-name-listing.ts +215 -36
  871. package/src/tickers/company-name.ts +43 -0
  872. package/src/tickers/index-roots.ts +47 -0
  873. package/src/tickers/instrument-label.ts +5 -1
  874. package/src/tickers/listing-fate.ts +30 -0
  875. package/src/tickers/metadata.ts +10 -0
  876. package/src/tickers/perpetual-listing.ts +5 -2
  877. package/src/tickers/search/home-listing.ts +75 -0
  878. package/src/tickers/search/index.ts +76 -27
  879. package/src/tickers/search/ranking.ts +54 -4
  880. package/src/tickers/search/upsert.ts +29 -0
  881. package/src/tickers/terminal-codes.ts +416 -40
  882. package/src/time-series/bar-aggregation.ts +243 -0
  883. package/src/time-series/base-series.ts +307 -0
  884. package/src/time-series/chart-bounds.ts +349 -0
  885. package/src/time-series/chart-seed.ts +142 -0
  886. package/src/time-series/economic.ts +5 -0
  887. package/src/time-series/fundamentals.ts +18 -3
  888. package/src/time-series/history-acquisition.ts +499 -0
  889. package/src/time-series/leverage.ts +100 -0
  890. package/src/time-series/market-resolution.ts +4 -2
  891. package/src/time-series/market.ts +2 -1
  892. package/src/time-series/price-comparison.ts +175 -30
  893. package/src/time-series/range.ts +9 -1
  894. package/src/time-series/resolution.ts +174 -16
  895. package/src/time-series/resolve-context.ts +157 -0
  896. package/src/time-series/resolve.ts +126 -1577
  897. package/src/time-series/series-name.ts +38 -0
  898. package/src/time-series/series-presentation.ts +208 -0
  899. package/src/time-series/spec.ts +11 -6
  900. package/src/time-series/studies.ts +109 -12
  901. package/src/time-series/tail-reconcile.ts +121 -0
  902. package/src/time-series/types.ts +29 -2
  903. package/src/time-series/use-chart-resolution.ts +4 -5
  904. package/src/types/broker.ts +10 -0
  905. package/src/types/config.ts +14 -0
  906. package/src/types/data-provider.ts +20 -0
  907. package/src/types/exchange-rate.ts +6 -0
  908. package/src/types/financials.ts +104 -7
  909. package/src/types/headless.ts +83 -6
  910. package/src/types/instrument.ts +3 -0
  911. package/src/types/issuer-listings.ts +28 -0
  912. package/src/types/plugin.ts +65 -8
  913. package/src/types/price-history.ts +2 -0
  914. package/src/types/ticker.ts +13 -0
  915. package/src/types/trading.ts +59 -1
  916. package/src/ui/ascii-font.ts +13 -1
  917. package/src/ui/host.tsx +6 -1
  918. package/src/updater/command-names.ts +175 -0
  919. package/src/updater/failure.ts +163 -0
  920. package/src/updater/index.ts +97 -28
  921. package/src/utils/calendar-date.ts +32 -15
  922. package/src/utils/cash-runway.ts +241 -0
  923. package/src/utils/central-banks.ts +42 -0
  924. package/src/utils/cli-output.ts +259 -80
  925. package/src/utils/contract-month.ts +16 -0
  926. package/src/utils/crypto-pair.ts +61 -3
  927. package/src/utils/currency-pair.ts +26 -0
  928. package/src/utils/currency-units.ts +29 -0
  929. package/src/utils/datetime-format.ts +10 -0
  930. package/src/utils/debug-log.ts +1 -1
  931. package/src/utils/decimal-comma.ts +39 -6
  932. package/src/utils/exchange-announcements.ts +71 -0
  933. package/src/utils/exchange-rate-snapshot.ts +10 -0
  934. package/src/utils/financial-statements.ts +83 -4
  935. package/src/utils/format.ts +34 -16
  936. package/src/utils/fundamentals.ts +150 -34
  937. package/src/utils/fx-market-hours.ts +10 -1
  938. package/src/utils/latest-financial-period.ts +8 -0
  939. package/src/utils/linux-libc.ts +54 -0
  940. package/src/utils/market-capitalization.ts +111 -15
  941. package/src/utils/max-drawdown.ts +64 -0
  942. package/src/utils/network-failure.ts +83 -0
  943. package/src/utils/option-expiry.ts +139 -7
  944. package/src/utils/price-earnings.ts +11 -5
  945. package/src/utils/price-history.ts +18 -8
  946. package/src/utils/price-window.ts +131 -0
  947. package/src/utils/release-date.ts +47 -0
  948. package/src/utils/sec.ts +71 -0
  949. package/src/utils/throttled-fetch.ts +11 -4
  950. package/src/utils/trailing-eps.ts +67 -0
  951. package/src/utils/typed-text.ts +21 -0
  952. package/src/utils/utc-time.ts +24 -1
  953. package/src/version.ts +6 -0
  954. package/src/cli/pane-functions/screenshot.ts +0 -2122
@@ -10,7 +10,8 @@ import { matchPrefix, type Command } from "../../commands/registry";
10
10
  import type { ResultItem } from "../../list/model";
11
11
  import type { CommandBarCategoryPriorities } from "../../view-model";
12
12
  import type { CommandBarRoute } from "../../workflow/types";
13
- import { normalizeCommandTickerSearchText } from "../ticker-search/results";
13
+ import { normalizeCommandTickerSearchText, readRootTickerQuery } from "../ticker-search/results";
14
+ import { endsInLegalForm, readNearMissListing, readTerminalListingCode } from "../../../../tickers/terminal-codes";
14
15
  import { useTickerSearchRouteResults } from "../ticker-search/route";
15
16
  import { buildRootResultModel, type RootResultModel } from "./results";
16
17
  import { useRootProviderSearch } from "./provider-search";
@@ -52,6 +53,7 @@ interface UseCommandBarRootRuntimeOptions {
52
53
  ): void | Promise<void>;
53
54
  getAvailablePaneShortcutTemplates(query: string): PaneTemplateDef[];
54
55
  getRecentPaneTemplate?: (id: string, arg?: string) => PaneTemplateDef | undefined;
56
+ leadingShortcutCode?: string | null;
55
57
  getTickers(): AppState["tickers"];
56
58
  hasPaneSettings(paneId: string): boolean;
57
59
  localTickerSearchResultItems(query?: string, options?: { category?: string; limit?: number }): ResultItem[];
@@ -114,6 +116,7 @@ export function useCommandBarRootRuntime({
114
116
  executeCollectionCommand,
115
117
  getAvailablePaneShortcutTemplates,
116
118
  getRecentPaneTemplate,
119
+ leadingShortcutCode,
117
120
  getTickers,
118
121
  hasPaneSettings,
119
122
  localTickerSearchResultItems,
@@ -196,6 +199,7 @@ export function useCommandBarRootRuntime({
196
199
  getAvailablePaneShortcutTemplates,
197
200
  getRecentPaneTemplate,
198
201
  hasPaneSettings,
202
+ leadingShortcutCode,
199
203
  localTickerSearchResultItems,
200
204
  nonShortcutPaneTemplateItems,
201
205
  openModeRoute,
@@ -229,6 +233,7 @@ export function useCommandBarRootRuntime({
229
233
  getAvailablePaneShortcutTemplates,
230
234
  getRecentPaneTemplate,
231
235
  hasPaneSettings,
236
+ leadingShortcutCode,
232
237
  localTickerSearchResultItems,
233
238
  nonShortcutPaneTemplateItems,
234
239
  openModeRoute,
@@ -246,8 +251,9 @@ export function useCommandBarRootRuntime({
246
251
  tickerActionItems,
247
252
  ]);
248
253
 
254
+ // `DES VOD LN` searches the listing the code names, as Enter opens it; `DES SAP SE` the company.
249
255
  const rootSecurityDescriptionArg = activeMatch?.command.id === "security-description" && activeMatch.arg.length >= 1
250
- ? activeMatch.arg
256
+ ? (endsInLegalForm(activeMatch.arg) ? null : readTerminalListingCode(activeMatch.arg)?.key) ?? readNearMissListing(activeMatch.arg)?.symbol ?? activeMatch.arg
251
257
  : null;
252
258
  // Free text that no prefix claims also goes to symbol search, so "nvidia"
253
259
  // finds NVDA without the backtick. Skipped when a local row already carries
@@ -257,10 +263,15 @@ export function useCommandBarRootRuntime({
257
263
  if (currentRoute || activeMatch || rootShortcutIntent.kind !== "none") return null;
258
264
  return listingChoiceQuery(rootQuery);
259
265
  }, [activeMatch, currentRoute, rootQuery, rootShortcutIntent.kind]);
266
+ // `VOD LN`, `AAPL GP` and `700.HK` search the symbol they are read as, and the rows say which listing they name.
267
+ const rootTickerReading = useMemo(() => (
268
+ currentRoute || activeMatch || rootShortcutIntent.kind !== "none" || rootListingChoice ? null : readRootTickerQuery(rootQuery)
269
+ ), [activeMatch, currentRoute, rootListingChoice, rootQuery, rootShortcutIntent.kind]);
260
270
  const rootPlainTickerSearchArg = useMemo(() => {
261
271
  if (currentRoute || activeMatch || rootShortcutIntent.kind !== "none") return null;
262
272
  // An explicit venue choice also searches one-letter symbols and names shared with local actions.
263
273
  if (rootListingChoice) return rootListingChoice.symbol;
274
+ if (rootTickerReading) return rootTickerReading.search;
264
275
  const trimmed = rootQuery.trim();
265
276
  const symbolQuery = symbolSearchQuery(trimmed);
266
277
  if (symbolQuery.length < 2) return null;
@@ -277,7 +288,7 @@ export function useCommandBarRootRuntime({
277
288
  && normalizeCommandTickerSearchText(item.label) === normalizedQuery
278
289
  ));
279
290
  return hasExactLocalRow ? null : symbolQuery;
280
- }, [activeMatch, currentRoute, pluginInstallItem, rootListingChoice, rootQuery, rootResultModel.items, rootShortcutIntent.kind]);
291
+ }, [activeMatch, currentRoute, pluginInstallItem, rootListingChoice, rootQuery, rootResultModel.items, rootShortcutIntent.kind, rootTickerReading]);
281
292
  const rootTickerSearchArg = rootSecurityDescriptionArg ?? rootPlainTickerSearchArg;
282
293
 
283
294
  const {
@@ -297,6 +308,7 @@ export function useCommandBarRootRuntime({
297
308
  readTickerSearchCache,
298
309
  rootPlainTickerSearchArg,
299
310
  listingSuffix: rootPlainTickerSearchArg && rootListingChoice ? rootListingChoice.suffix : null,
311
+ reading: rootPlainTickerSearchArg ? rootTickerReading : null,
300
312
  rootResultItems: rootResultModel.items,
301
313
  rootTickerSearchArg,
302
314
  tickers: state.tickers,
@@ -9,6 +9,8 @@ import type { ResultItem } from "../../list/model";
9
9
 
10
10
  const DEFAULT_MIN_QUERY_LENGTH = 3;
11
11
  const DEFAULT_DEBOUNCE_MS = 300;
12
+ /** The corpus answers in well under a second; past this a provider is stuck, not slow. */
13
+ const DEFAULT_PROVIDER_TIMEOUT_MS = 8_000;
12
14
  const PROVIDER_ROW_PREFIX = "search-provider:";
13
15
 
14
16
  /** A row a plugin search provider contributed, as opposed to one the bar resolved itself. */
@@ -135,7 +137,9 @@ function useProviderMatchItems({
135
137
  * Runs plugin search providers for the root list. Each provider debounces and
136
138
  * aborts on its own, answers are memoized for the life of the bar, and rows are
137
139
  * only ever added to the static list: a provider that fails, hangs, or answers
138
- * late leaves what the command bar already resolved exactly as it was.
140
+ * late leaves what the command bar already resolved exactly as it was. Every
141
+ * provider settles: one that has not answered within its `timeoutMs` is
142
+ * aborted and counts as empty, so the bar never keeps searching for it.
139
143
  * Providers that answer from memory skip all of that and come back as
140
144
  * `providerMatchItems`, for the bar to rank with its own matches.
141
145
  */
@@ -235,9 +239,27 @@ export function useCommandBarSearchProviders({
235
239
  const controller = new AbortController();
236
240
  abortsRef.current.set(provider.id, controller);
237
241
  void (async () => {
242
+ let deadline: ReturnType<typeof setTimeout> | undefined;
243
+ // Ends the wait on the deadline, and on an abort, so a provider that
244
+ // ignores its signal does not hold the request for the full deadline.
245
+ const timedOut = new Promise<null>((resolve) => {
246
+ deadline = setTimeout(() => resolve(null), provider.timeoutMs ?? DEFAULT_PROVIDER_TIMEOUT_MS);
247
+ controller.signal.addEventListener("abort", () => resolve(null), { once: true });
248
+ });
238
249
  try {
239
- const results = await provider.provide(trimmed, contextRef.current, controller.signal);
250
+ const results = await Promise.race([
251
+ provider.provide(trimmed, contextRef.current, controller.signal),
252
+ timedOut,
253
+ ]);
240
254
  if (controller.signal.aborted) return;
255
+ if (!results) {
256
+ // A provider that never answers is a provider with nothing to
257
+ // say: the bar stops searching for it, and what it sends later is
258
+ // dropped. Nothing is memoized, so a later visit to the text asks again.
259
+ controller.abort();
260
+ publish(provider, trimmed, []);
261
+ return;
262
+ }
241
263
  cacheRef.current.set(`${provider.id}\n${trimmed}`, results);
242
264
  publish(provider, trimmed, results);
243
265
  } catch {
@@ -246,6 +268,7 @@ export function useCommandBarSearchProviders({
246
268
  if (controller.signal.aborted) return;
247
269
  publish(provider, trimmed, []);
248
270
  } finally {
271
+ clearTimeout(deadline);
249
272
  if (abortsRef.current.get(provider.id) === controller) {
250
273
  abortsRef.current.delete(provider.id);
251
274
  setLoading(provider.id, false);
@@ -26,6 +26,7 @@ interface PaneTemplateItemOptions {
26
26
 
27
27
  interface RootSelectionCommandOptions {
28
28
  activeTickerSymbol: string | null;
29
+ promptTickerSymbol?: string | null;
29
30
  availableCommands: Command[];
30
31
  createPaneTemplateItem: (template: PaneTemplateDef, options?: PaneTemplateItemOptions) => ResultItem;
31
32
  createPluginCommandItem: (command: CommandDef, options?: { shortcutArg?: string }) => ResultItem;
@@ -40,7 +41,7 @@ interface RootSelectionCommandOptions {
40
41
  openPaneTemplateWorkflow: (template: PaneTemplateDef, options?: { arg?: string }) => void;
41
42
  pluginCommandResultItems: (command: CommandDef, shortcutArg: string) => ResultItem[];
42
43
  runDirectCommand: (command: Command, arg: string) => void;
43
- runSecurityDescriptionShortcut: (query?: string) => void | Promise<void>;
44
+ runSecurityDescriptionShortcut: (query?: string, options?: { forceNewPane?: boolean }) => void | Promise<void>;
44
45
  setRootQuery: (query: string) => void;
45
46
  startThemePicker: (arg: string) => void;
46
47
  }
@@ -54,6 +55,7 @@ export function acceptRootShortcutTabAction(options: RootSelectionCommandOptions
54
55
  pluginCommands: options.getAvailablePluginCommands(),
55
56
  paneTemplates: options.getAvailablePaneShortcutTemplates(options.query),
56
57
  activeTicker: options.activeTickerSymbol,
58
+ promptTicker: options.promptTickerSymbol,
57
59
  });
58
60
  if (intent.kind === "none") return false;
59
61
  if (intent.kind === "inferred-complete" && intent.completionQuery) {
@@ -103,6 +105,7 @@ export function buildImmediateRootSelection(options: RootSelectionCommandOptions
103
105
  pluginCommands: options.getAvailablePluginCommands(),
104
106
  paneTemplates: options.getAvailablePaneShortcutTemplates(options.query),
105
107
  activeTicker: options.activeTickerSymbol,
108
+ promptTicker: options.promptTickerSymbol,
106
109
  });
107
110
  if (intent.kind !== "none" && intent.source === "pane-template") {
108
111
  return options.createPaneTemplateItem(intent.template, {
@@ -139,6 +142,7 @@ export function buildImmediateRootSelection(options: RootSelectionCommandOptions
139
142
  right: match.command.prefix,
140
143
  shortcutQuery: match.command.prefix,
141
144
  action: () => { void options.runSecurityDescriptionShortcut(inferredTicker); },
145
+ secondaryAction: () => { void options.runSecurityDescriptionShortcut(inferredTicker, { forceNewPane: true }); },
142
146
  };
143
147
  }
144
148
  return {
@@ -159,6 +163,7 @@ export function buildImmediateRootSelection(options: RootSelectionCommandOptions
159
163
  right: match.command.prefix,
160
164
  shortcutQuery: match.command.prefix,
161
165
  action: () => { void options.runSecurityDescriptionShortcut(match.arg); },
166
+ secondaryAction: () => { void options.runSecurityDescriptionShortcut(match.arg, { forceNewPane: true }); },
162
167
  };
163
168
  }
164
169
 
@@ -1,4 +1,5 @@
1
1
  import type { AppState } from "../../../../state/app/context";
2
+ import { commandPromptTicker } from "../../../../layout/selected-ticker";
2
3
  import { normalizeTickerInput } from "../../../../tickers/search";
3
4
  import {
4
5
  getCollectionCommandAction,
@@ -37,7 +38,9 @@ export function buildRootShortcutFeedback({
37
38
  if (rootShortcutIntent.template.shortcut?.argOptional && !rootShortcutIntent.argText) {
38
39
  return `Shortcut: ${rootShortcutIntent.label}`;
39
40
  }
40
- const symbol = normalizeTickerInput(activeTickerSymbol, rootShortcutIntent.argText);
41
+ // Same ticker the intent inferred: the prompt's, so a linked desk counts.
42
+ const inferFrom = commandPromptTicker(state)?.symbol ?? activeTickerSymbol;
43
+ const symbol = normalizeTickerInput(inferFrom, rootShortcutIntent.argText);
41
44
  if (symbol) {
42
45
  return rootShortcutIntent.kind === "inferred-complete"
43
46
  ? `Shortcut: ${rootShortcutIntent.label} for ${symbol} · Tab to accept`
@@ -121,18 +121,42 @@ function buildShortcutCandidates(
121
121
  ].sort((a, b) => b.prefix.length - a.prefix.length);
122
122
  }
123
123
 
124
+ /**
125
+ * The function code the text starts with, whatever follows it: `MOST foo`
126
+ * leads with MOST though MOST takes no argument. Null for any other text.
127
+ */
128
+ export function leadingShortcutCode({
129
+ query,
130
+ commands,
131
+ pluginCommands = [],
132
+ paneTemplates,
133
+ }: {
134
+ query: string;
135
+ commands: Command[];
136
+ pluginCommands?: CommandDef[];
137
+ paneTemplates: PaneTemplateDef[];
138
+ }): string | null {
139
+ const first = query.trim().split(/\s+/)[0]?.toUpperCase();
140
+ if (!first) return null;
141
+ return buildShortcutCandidates(commands, pluginCommands, paneTemplates)
142
+ .find((candidate) => candidate.prefix === first)?.prefix ?? null;
143
+ }
144
+
124
145
  export function parseRootShortcutIntent({
125
146
  query,
126
147
  commands,
127
148
  pluginCommands = [],
128
149
  paneTemplates,
129
150
  activeTicker,
151
+ promptTicker = null,
130
152
  }: {
131
153
  query: string;
132
154
  commands: Command[];
133
155
  pluginCommands?: CommandDef[];
134
156
  paneTemplates: PaneTemplateDef[];
135
157
  activeTicker: string | null;
158
+ /** The command prompt's instrument, used when a pane requires a ticker and the focused pane has none. */
159
+ promptTicker?: string | null;
136
160
  }): ShortcutIntent {
137
161
  const trimmed = query.trim();
138
162
  if (!trimmed) return { kind: "none" };
@@ -145,9 +169,12 @@ export function parseRootShortcutIntent({
145
169
  if (!match) return { kind: "none" };
146
170
 
147
171
  const argText = trimmed.slice(match.prefix.length).trim();
148
- const inferredArg = match.source === "pane-template" && match.template?.shortcut?.argOptional
149
- ? null
150
- : inferShortcutArg(match.argKind, activeTicker);
172
+ // A pane that requires a ticker takes the one already in the prompt. An
173
+ // optional ticker stays unbound, and other commands keep the focused ticker.
174
+ const inferFrom = match.source === "pane-template"
175
+ ? (match.template?.shortcut?.argOptional ? null : (promptTicker ?? activeTicker))
176
+ : activeTicker;
177
+ const inferredArg = inferShortcutArg(match.argKind, inferFrom);
151
178
  const completionQuery = inferredArg ? `${match.prefix} ${inferredArg}` : null;
152
179
 
153
180
  let kind: Exclude<ShortcutIntentKind, "none">;
@@ -11,7 +11,9 @@ import {
11
11
  } from "../../../../tickers/search/asset-classes";
12
12
  import type { ResultItem } from "../../list/model";
13
13
  import { currencyPairCode } from "../../../../utils/currency-pair";
14
- import { canonicalExchange, exchangeCodeVenues, parsePublicTickerKey, publicExchange } from "../../../../utils/exchanges";
14
+ import { canonicalExchange, exchangeCodeVenues, isUsListingExchange, parsePublicTickerKey, publicExchange } from "../../../../utils/exchanges";
15
+ import { endsInLegalForm, readNearMissListing, readTerminalListingCode, unknownBloombergMarket } from "../../../../tickers/terminal-codes";
16
+ import { listingSuffixExchange, tickerHasListingSuffix } from "../../../../sources/listing-symbols";
15
17
  import { answersToFutureName, answersToIndexCode, compactSearchText, getIssuerGroupKey, isExplicitMarketSymbol } from "../../../../tickers/search/ranking";
16
18
  import { isProviderBusy } from "../../../../sources/provider-errors";
17
19
 
@@ -165,12 +167,16 @@ export function mergePlainRootTickerResults(
165
167
  query: string,
166
168
  providerItems: ResultItem[],
167
169
  rootItems: ResultItem[],
170
+ /** What the typed text reads as when it is a terminal's code or a near miss (`readRootTickerQuery`). */
171
+ reading: RootTickerReading | null = null,
168
172
  ): ResultItem[] {
169
173
  const seenExactVenues = new Set<string>();
170
174
  const seenLooseSymbols = new Set<string>();
171
175
  const symbolsWithExact = new Set<string>();
172
176
  const candidates: ResultItem[] = [];
173
- const isExact = (item: ResultItem) => item.category === "Exact Match" || isExactTickerResultMatch(item, query);
177
+ const isExact = reading
178
+ ? (item: ResultItem) => reading.names(item)
179
+ : (item: ResultItem) => item.category === "Exact Match" || isExactTickerResultMatch(item, query);
174
180
  for (const item of providerItems) {
175
181
  if (!isInstrumentItem(item)) continue;
176
182
  const label = item.label.trim().toUpperCase();
@@ -195,13 +201,76 @@ export function mergePlainRootTickerResults(
195
201
  return busy.length > 0 ? [...rootItems, ...busy] : rootItems;
196
202
  }
197
203
 
204
+ const exact = instruments.filter(isExact);
205
+ // `AAPL GY` names a listing search does not have, `700.HK` nearly names one: the row it was read from is offered.
206
+ const meant = reading && exact.length === 0 ? instruments.find(reading.meant) : undefined;
198
207
  return [
199
- ...instruments.filter(isExact).map((item) => ({ ...item, category: "Exact Match" })),
208
+ ...exact.map((item) => ({ ...item, category: "Exact Match" })),
209
+ ...meant ? [{ ...meant, category: DID_YOU_MEAN_CATEGORY }] : [],
200
210
  ...rootItems,
201
- ...instruments.filter((item) => !isExact(item)).map((item) => ({ ...item, category: ROOT_INSTRUMENTS_CATEGORY })),
211
+ ...instruments.filter((item) => !isExact(item) && item !== meant).map((item) => ({ ...item, category: ROOT_INSTRUMENTS_CATEGORY })),
202
212
  ];
203
213
  }
204
214
 
215
+ /** The section of the row a near-miss or a terminal's code was read as, when it names no listing outright. */
216
+ export const DID_YOU_MEAN_CATEGORY = "Did you mean";
217
+
218
+ /** What a plain root query reads as when it is written the way a terminal or a broker writes a listing. */
219
+ export interface RootTickerReading {
220
+ /** The symbol search is asked for: the code's ticker (VOD for `VOD LN`), or the working form of a near miss (0700.HK). */
221
+ search: string;
222
+ /** Rows on the listing the text names: VOD on LSE for `VOD LN`. They are the exact match. */
223
+ names: (item: ResultItem) => boolean;
224
+ /** Rows of the symbol it was read from, the first offered as what it meant when no row is named: AAPL for `AAPL GY`. */
225
+ meant: (item: ResultItem) => boolean;
226
+ }
227
+
228
+ /** The symbol and venue a ticker row stands for: SAP:XETR's or SAP on the XETRA row, in canonical codes. */
229
+ function rowListing(item: ResultItem): { symbol: string; exchange: string } {
230
+ const label = parsePublicTickerKey(item.label.trim().toUpperCase());
231
+ return { symbol: label.symbol.replace(/[-/]/g, "."), exchange: canonicalExchange(label.exchange || item.right) };
232
+ }
233
+
234
+ /**
235
+ * A plain root query written as a Bloomberg code (`VOD LN`, `7203 JP Equity`,
236
+ * `SPX Index`), as one whose market code no venue answers to (`AAPL GP`), or
237
+ * nearly as a listing (`700.HK`, `6758.JP`, `BRK/B`), read by the one parser
238
+ * every command reads them with. A code names its listing; the others only
239
+ * name the symbol they were read from, offered as what was meant. Null for
240
+ * anything else, which the bar searches as typed, and for a name before a
241
+ * legal form (`SAP SE`, `SIEMENS AG`), which search finds as the company.
242
+ */
243
+ export function readRootTickerQuery(query: string): RootTickerReading | null {
244
+ const trimmed = query.trim();
245
+ if (endsInLegalForm(trimmed)) return null;
246
+ const isInstrument = (item: ResultItem) => item.kind === "ticker" || item.kind === "search";
247
+ const ofSymbol = (symbol: string) => {
248
+ const wanted = symbol.toUpperCase().replace(/[-/]/g, ".");
249
+ return (item: ResultItem) => isInstrument(item) && rowListing(item).symbol === wanted;
250
+ };
251
+ const code = readTerminalListingCode(trimmed);
252
+ if (code?.terminal === "bloomberg") {
253
+ const listings = [code, ...code.alternatives ?? []];
254
+ const named = (item: ResultItem) => {
255
+ const row = rowListing(item);
256
+ return isInstrument(item) && listings.some((listing) => row.symbol === listing.symbol.replace(/[-/]/g, ".")
257
+ && (!code.market ? true : listing.exchange ? row.exchange === listing.exchange : isUsListingExchange(row.exchange)));
258
+ };
259
+ return { search: code.symbol, names: named, meant: ofSymbol(code.symbol) };
260
+ }
261
+ const unknown = unknownBloombergMarket(trimmed);
262
+ if (unknown) return { search: unknown.symbol, names: () => false, meant: ofSymbol(unknown.symbol) };
263
+ const nearMiss = readNearMissListing(trimmed);
264
+ if (!nearMiss) return null;
265
+ // 0700.HK is listed as 0700 on HKEX: the row of the symbol before its suffix.
266
+ const { symbol } = parsePublicTickerKey(nearMiss.symbol);
267
+ const root = tickerHasListingSuffix(symbol) ? symbol.slice(0, symbol.indexOf(".")) : symbol;
268
+ const suffixVenue = listingSuffixExchange(symbol);
269
+ const meant = (item: ResultItem) => (ofSymbol(root)(item) && (!suffixVenue || rowListing(item).exchange === suffixVenue))
270
+ || (isInstrument(item) && isExactTickerResultMatch(item, nearMiss.symbol));
271
+ return { search: nearMiss.symbol, names: () => false, meant };
272
+ }
273
+
205
274
  function venueMatchesSuffix(item: ResultItem, suffix: string): boolean {
206
275
  if (!suffix) return true;
207
276
  const displayed = (item.right ?? "").trim().toUpperCase();
@@ -2,7 +2,8 @@ import { useCallback, type MutableRefObject } from "react";
2
2
  import type { AppState } from "../../state/app/context";
3
3
  import type { TickerRecord } from "../../types/ticker";
4
4
  import { t } from "../../i18n";
5
- import { listingChoiceQuery } from "../../tickers/search";
5
+ import { findExactTickerSearchMatch, listingChoiceQuery } from "../../tickers/search";
6
+ import { isKnownExchangeCode, parsePublicTickerKey } from "../../utils/exchanges";
6
7
  import type { PluginRegistry } from "../../plugins/registry";
7
8
  import type { Command } from "./commands/registry";
8
9
  import type {
@@ -22,6 +23,7 @@ import {
22
23
  import type { OpenInlineConfirm } from "./routing/confirm";
23
24
  import { activatePickerSelectionAction } from "./picker-activation";
24
25
  import type { RunRootRow } from "./routes/root/search-report";
26
+ import type { ShortcutIntent } from "./routes/root/shortcuts";
25
27
 
26
28
  type OpenModeRouteFn = (
27
29
  screen: "ticker-search" | "layout",
@@ -39,6 +41,7 @@ type ExecuteCollectionCommandFn = (
39
41
 
40
42
  interface UseCommandBarSelectionRuntimeOptions {
41
43
  activeTickerSymbol: string | null;
44
+ promptTickerSymbol?: string | null;
42
45
  availableCommands: Command[];
43
46
  clearThemePreview: (themeId: string) => void;
44
47
  closeAll: (options?: { revertThemePreview?: boolean }) => void;
@@ -64,6 +67,8 @@ interface UseCommandBarSelectionRuntimeOptions {
64
67
  rootModeKindRef: MutableRefObject<CommandBarMode>;
65
68
  rootQuery: string;
66
69
  rootQueryRef: MutableRefObject<string>;
70
+ rootSelectionNavigatedRef: MutableRefObject<boolean>;
71
+ rootShortcutIntent: ShortcutIntent;
67
72
  rootThemeBaseIdRef: MutableRefObject<string | null>;
68
73
  runDirectCommand: (command: Command, arg: string) => void;
69
74
  /**
@@ -72,7 +77,7 @@ interface UseCommandBarSelectionRuntimeOptions {
72
77
  * or rewrote the query. It never holds the row up.
73
78
  */
74
79
  runRootRow?: RunRootRow;
75
- runSecurityDescriptionShortcut: (query?: string) => void | Promise<void>;
80
+ runSecurityDescriptionShortcut: (query?: string, options?: { forceNewPane?: boolean }) => void | Promise<void>;
76
81
  setRootQuery: (query: string) => void;
77
82
  stateConfigLayout: AppState["config"]["layout"];
78
83
  stateRef: MutableRefObject<AppState>;
@@ -82,6 +87,7 @@ interface UseCommandBarSelectionRuntimeOptions {
82
87
 
83
88
  export function useCommandBarSelectionRuntime({
84
89
  activeTickerSymbol,
90
+ promptTickerSymbol = null,
85
91
  availableCommands,
86
92
  clearThemePreview,
87
93
  closeAll,
@@ -102,6 +108,8 @@ export function useCommandBarSelectionRuntime({
102
108
  rootModeKindRef,
103
109
  rootQuery,
104
110
  rootQueryRef,
111
+ rootSelectionNavigatedRef,
112
+ rootShortcutIntent,
105
113
  rootThemeBaseIdRef,
106
114
  runDirectCommand,
107
115
  runRootRow,
@@ -131,6 +139,7 @@ export function useCommandBarSelectionRuntime({
131
139
 
132
140
  const resolveImmediateRootSelection = useCallback((query: string): ResultItem | null => buildImmediateRootSelection({
133
141
  activeTickerSymbol,
142
+ promptTickerSymbol,
134
143
  availableCommands,
135
144
  createPaneTemplateItem,
136
145
  createPluginCommandItem,
@@ -147,6 +156,7 @@ export function useCommandBarSelectionRuntime({
147
156
  startThemePicker,
148
157
  }), [
149
158
  activeTickerSymbol,
159
+ promptTickerSymbol,
150
160
  availableCommands,
151
161
  createPaneTemplateItem,
152
162
  createPluginCommandItem,
@@ -171,6 +181,7 @@ export function useCommandBarSelectionRuntime({
171
181
  const query = rootQueryRef.current;
172
182
  const accept = () => acceptRootShortcutTabAction({
173
183
  activeTickerSymbol,
184
+ promptTickerSymbol,
174
185
  availableCommands,
175
186
  createPaneTemplateItem,
176
187
  createPluginCommandItem,
@@ -196,6 +207,7 @@ export function useCommandBarSelectionRuntime({
196
207
  return accepted;
197
208
  }, [
198
209
  activeTickerSymbol,
210
+ promptTickerSymbol,
199
211
  availableCommands,
200
212
  createPaneTemplateItem,
201
213
  createPluginCommandItem,
@@ -267,11 +279,37 @@ export function useCommandBarSelectionRuntime({
267
279
  const activateListSelection = useCallback((options?: { secondary?: boolean; item?: ResultItem }) => {
268
280
  const listState = visibleListStateRef.current;
269
281
  if (!listState) return;
270
- const typed = options?.item
271
- ? null
272
- : (!currentRoute && rootQueryRef.current !== rootQuery
273
- ? resolveImmediateRootSelection(rootQueryRef.current)
274
- : null);
282
+ // Enter submits the typed command until a row is deliberately chosen.
283
+ // Search ranks suggestions by relevance; its first namesake must not
284
+ // replace the listing the shared ticker resolver would open.
285
+ const queryChanged = rootQueryRef.current !== rootQuery;
286
+ const tickerArgument = rootShortcutIntent.kind !== "none" && rootShortcutIntent.argKind === "ticker"
287
+ ? rootShortcutIntent.argText : null;
288
+ const listingQuery = listingChoiceQuery(tickerArgument ?? rootQueryRef.current);
289
+ const choosingVenue = listingQuery && !isKnownExchangeCode(listingQuery.suffix);
290
+ const submitTyped = !options?.item && !currentRoute
291
+ && (queryChanged || (!rootSelectionNavigatedRef.current && !choosingVenue));
292
+ let typed = submitTyped && (queryChanged || tickerArgument !== null)
293
+ ? resolveImmediateRootSelection(rootQueryRef.current) : null;
294
+ const first = listState.results[listState.selectedIdx];
295
+ if (typed && !queryChanged && rootShortcutIntent.kind !== "none" && rootShortcutIntent.argKind === "ticker"
296
+ && first && (first.kind === "ticker" || first.kind === "search")) {
297
+ const argument = rootShortcutIntent.argText;
298
+ // Company names and partial symbols still accept the suggested match.
299
+ // An exact symbol or named venue goes through listing resolution.
300
+ if (!parsePublicTickerKey(argument).exchange && !findExactTickerSearchMatch(
301
+ listState.results.filter((item) => item.kind === "ticker" || item.kind === "search"), argument,
302
+ )) typed = null;
303
+ }
304
+ // A plain symbol follows the same path once it is the default ticker row.
305
+ // Commands and company-name searches keep their own default actions.
306
+ const plainSymbol = submitTyped && !typed && first && (first.kind === "ticker" || first.kind === "search")
307
+ && findExactTickerSearchMatch([first], rootQueryRef.current);
308
+ if (plainSymbol && first) {
309
+ const symbol = rootQueryRef.current;
310
+ typed = { ...first, action: () => runSecurityDescriptionShortcut(symbol),
311
+ secondaryAction: () => runSecurityDescriptionShortcut(symbol, { forceNewPane: true }) };
312
+ }
275
313
  const selected = options?.item ?? typed ?? listState.results[listState.selectedIdx];
276
314
  if (!selected || selected.disabled) return;
277
315
 
@@ -340,9 +378,8 @@ export function useCommandBarSelectionRuntime({
340
378
  item: selected,
341
379
  query,
342
380
  rank: selected === typed ? 0 : Math.max(0, listState.results.indexOf(selected)),
343
- // Text that ran before its list rendered is the shortcut itself;
344
- // otherwise only the row the shortcut resolves to is.
345
- isShortcut: () => selected === typed || resolveImmediateRootSelection(query)?.id === selected.id,
381
+ // A plain symbol stays a ticker choice; a submitted command is the shortcut itself.
382
+ isShortcut: () => !plainSymbol && (selected === typed || resolveImmediateRootSelection(query)?.id === selected.id),
346
383
  }, run);
347
384
  }, [
348
385
  closeAll,
@@ -355,7 +392,10 @@ export function useCommandBarSelectionRuntime({
355
392
  resolveImmediateRootSelection,
356
393
  rootQuery,
357
394
  rootQueryRef,
395
+ rootSelectionNavigatedRef,
396
+ rootShortcutIntent,
358
397
  runRootRow,
398
+ runSecurityDescriptionShortcut,
359
399
  stateConfigLayout,
360
400
  stateRef,
361
401
  visibleListStateRef,
@@ -22,7 +22,8 @@ import { createQuickLookTickerCandidates } from "../routes/ticker-search/results
22
22
  import { useCommandSearchReport } from "../routes/root/search-report";
23
23
  import { useAppStateRef } from "../../../state/app/context";
24
24
  import { listingChoiceQuery } from "../../../tickers/search";
25
- import { parseRootShortcutIntent } from "../routes/root/shortcuts";
25
+ import { commandPromptTicker } from "../../../layout/selected-ticker";
26
+ import { leadingShortcutCode, parseRootShortcutIntent } from "../routes/root/shortcuts";
26
27
  import { useRootPluginInstallItem } from "../routes/root/plugin-install";
27
28
  import { useRootPluginTurnOnItem } from "../routes/root/plugin-turn-on";
28
29
  import { useCommandBarThemePreview } from "../theme-preview";
@@ -227,13 +228,30 @@ export function CommandBar({
227
228
  [getAvailablePaneTemplates],
228
229
  );
229
230
 
231
+ const promptTickerSymbol = commandPromptTicker(state)?.symbol ?? null;
230
232
  const rootShortcutIntent = useMemo(() => parseRootShortcutIntent({
231
233
  query: rootQuery,
232
234
  commands: availableCommands,
233
235
  pluginCommands: getAvailablePluginCommands(),
234
236
  paneTemplates: getAvailablePaneShortcutTemplates(rootQuery),
235
237
  activeTicker: activeTickerSymbol,
236
- }), [activeTickerSymbol, availableCommands, getAvailablePaneShortcutTemplates, getAvailablePluginCommands, rootQuery]);
238
+ promptTicker: promptTickerSymbol,
239
+ }), [activeTickerSymbol, availableCommands, getAvailablePaneShortcutTemplates, getAvailablePluginCommands, promptTickerSymbol, rootQuery]);
240
+ // Every code of an enabled plugin, whether or not it can open here, so text
241
+ // it leads is never answered with only the sign-up offer.
242
+ const leadingCode = useMemo(() => {
243
+ if (rootShortcutIntent.kind !== "none") return null;
244
+ const disabled = new Set(state.config.disabledPlugins ?? []);
245
+ return leadingShortcutCode({
246
+ query: rootQuery,
247
+ commands: availableCommands,
248
+ pluginCommands: getAvailablePluginCommands(),
249
+ paneTemplates: [...pluginRegistry.paneTemplates.values()].filter((template) => {
250
+ const pluginId = pluginRegistry.getPaneTemplatePluginId(template.id);
251
+ return !pluginId || !disabled.has(pluginId);
252
+ }),
253
+ });
254
+ }, [availableCommands, getAvailablePluginCommands, pluginRegistry, rootQuery, rootShortcutIntent.kind, state.config.disabledPlugins]);
237
255
  const listingChoice = !currentRoute && rootShortcutIntent.kind === "none"
238
256
  ? listingChoiceQuery(rootQuery)
239
257
  : null;
@@ -433,6 +451,7 @@ export function CommandBar({
433
451
  executeCollectionCommand,
434
452
  getAvailablePaneShortcutTemplates,
435
453
  getRecentPaneTemplate,
454
+ leadingShortcutCode: leadingCode,
436
455
  getTickers: getTickerSearchTickers,
437
456
  hasPaneSettings,
438
457
  localTickerSearchResultItems,
@@ -492,6 +511,7 @@ export function CommandBar({
492
511
  setActiveListQuery,
493
512
  } = useCommandBarSelectionRuntime({
494
513
  activeTickerSymbol,
514
+ promptTickerSymbol,
495
515
  availableCommands,
496
516
  clearThemePreview,
497
517
  closeAll: closeAfterRun,
@@ -512,6 +532,8 @@ export function CommandBar({
512
532
  rootModeKindRef,
513
533
  rootQuery,
514
534
  rootQueryRef,
535
+ rootSelectionNavigatedRef,
536
+ rootShortcutIntent,
515
537
  rootThemeBaseIdRef,
516
538
  runDirectCommand,
517
539
  runRootRow,
@@ -186,6 +186,12 @@ const PLUGIN_INSTALL_SECTION_PRIORITY = -200;
186
186
  * it was derived from, which is a guess sitting above the fact behind it.
187
187
  */
188
188
  const EXACT_MATCH_SECTION_PRIORITY = -150;
189
+ /**
190
+ * The listing a near miss or a terminal's code was read as (`700.HK` as 0700
191
+ * on HKEX), when no row is the exact match: a fact the typed text points at,
192
+ * so it sits under an exact symbol and above the AI's guess.
193
+ */
194
+ const DID_YOU_MEAN_SECTION_PRIORITY = -120;
189
195
  /**
190
196
  * The AI leads the rest even though it is the slowest source (~600ms+): it
191
197
  * translates the sentence the user typed into commands, which is the answer to
@@ -211,6 +217,7 @@ function getCategoryPriority(category: string, options?: CommandBarSectionOption
211
217
  if (sectionOrder === "ranked") return 0;
212
218
  if (normalized === "ask ai") return ASSIST_SECTION_PRIORITY;
213
219
  if (normalized === "exact match") return EXACT_MATCH_SECTION_PRIORITY;
220
+ if (normalized === "did you mean") return DID_YOU_MEAN_SECTION_PRIORITY;
214
221
  if (category === PLUGIN_INSTALL_CATEGORY) return PLUGIN_INSTALL_SECTION_PRIORITY;
215
222
  if (normalized === "instruments") return INSTRUMENTS_SECTION_PRIORITY;
216
223
  if (normalized === "suggested") return SUGGESTED_SECTION_PRIORITY;
@@ -1,6 +1,6 @@
1
1
  import {
2
+ brokerDirectorySummary,
2
3
  brokerMethodLabel,
3
- brokerMethodSummary,
4
4
  type BrokerDirectoryEntry,
5
5
  type BrokerMethod,
6
6
  } from "../../../brokers/directory";
@@ -51,7 +51,7 @@ export function buildBrokerWorkflowRoute({
51
51
  options.push(...directory.map((entry) => ({
52
52
  label: entry.name,
53
53
  value: entry.key,
54
- description: brokerMethodSummary(entry),
54
+ description: brokerDirectorySummary(entry),
55
55
  })));
56
56
 
57
57
  const fields: CommandBarWorkflowField[] = [{