gloomberb 0.18.3 → 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 (886) 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/src/account/checkout-handoff.tsx +225 -0
  6. package/src/account/device-signin-dialog.tsx +2 -2
  7. package/src/account/device-signin.ts +2 -2
  8. package/src/account/upgrade-dialog.tsx +1 -1
  9. package/src/api-client/askg.ts +2 -2
  10. package/src/api-client/auth.ts +2 -2
  11. package/src/api-client/central-bank-rates.ts +6 -0
  12. package/src/api-client/collections.ts +5 -1
  13. package/src/api-client/cot.ts +2 -0
  14. package/src/api-client/crypto-etf-flows.ts +37 -0
  15. package/src/api-client/crypto-markets.ts +60 -0
  16. package/src/api-client/data.ts +84 -5
  17. package/src/api-client/doe.ts +15 -0
  18. package/src/api-client/equity-screener.ts +28 -0
  19. package/src/api-client/exchange-announcements.ts +38 -0
  20. package/src/api-client/fund-facts.ts +39 -0
  21. package/src/api-client/futures-curve.ts +9 -1
  22. package/src/api-client/hiring.ts +301 -0
  23. package/src/api-client/index.ts +22 -5
  24. package/src/api-client/market-discovery.ts +14 -0
  25. package/src/api-client/members.ts +6 -0
  26. package/src/api-client/mna.ts +6 -0
  27. package/src/api-client/paths.ts +18 -1
  28. package/src/api-client/request.ts +21 -4
  29. package/src/api-client/short-side-publications.ts +37 -0
  30. package/src/api-client/socket.ts +64 -4
  31. package/src/api-client/swap-curve.ts +35 -0
  32. package/src/api-client/themes.ts +7 -1
  33. package/src/api-client/types.ts +90 -2
  34. package/src/app/pane-runtime/plugin-bindings.ts +9 -2
  35. package/src/app/runtime/desktop-deeplink.ts +5 -5
  36. package/src/app/runtime/plugin-bindings.ts +2 -2
  37. package/src/app/runtime/startup.ts +13 -0
  38. package/src/app/star-prompt/status-line.tsx +2 -2
  39. package/src/architecture/core-builtin-allowlist.json +5 -2
  40. package/src/architecture/ui-literals-allowlist.json +3 -3
  41. package/src/architecture/ui-tokens-allowlist.json +1 -1
  42. package/src/brokers/broker-portfolio-sync.ts +37 -0
  43. package/src/brokers/directory.ts +11 -0
  44. package/src/brokers/logos.ts +3 -1
  45. package/src/brokers/signed-in/adapter.ts +304 -26
  46. package/src/brokers/signed-in/client.ts +14 -2
  47. package/src/brokers/signed-in/connect.ts +10 -2
  48. package/src/brokers/sync-broker-instance.ts +9 -1
  49. package/src/capabilities/chart-series.ts +22 -6
  50. package/src/cli/bank-section.ts +1 -1
  51. package/src/cli/base-converter.ts +23 -14
  52. package/src/cli/central-bank-events.ts +1 -1
  53. package/src/cli/command-options.ts +59 -4
  54. package/src/cli/commands/api.ts +9 -6
  55. package/src/cli/commands/broker.ts +2 -2
  56. package/src/cli/commands/command-utils.ts +2 -2
  57. package/src/cli/commands/crypto-hints.ts +7 -20
  58. package/src/cli/commands/fred-series.ts +4 -2
  59. package/src/cli/commands/keybindings.ts +2 -2
  60. package/src/cli/commands/market.ts +1117 -264
  61. package/src/cli/commands/news-hints.ts +2 -2
  62. package/src/cli/commands/news-search.ts +59 -6
  63. package/src/cli/commands/options-leaps.ts +41 -26
  64. package/src/cli/commands/overview.ts +121 -48
  65. package/src/cli/commands/plugins.ts +9 -9
  66. package/src/cli/commands/remote.ts +13 -10
  67. package/src/cli/commands/search.ts +64 -44
  68. package/src/cli/commands/system.ts +27 -19
  69. package/src/cli/commands/themes.ts +1 -1
  70. package/src/cli/commands/ticker.ts +192 -47
  71. package/src/cli/context.ts +3 -2
  72. package/src/cli/desktop-pane-shot-view.ts +2 -2
  73. package/src/cli/desktop-pane-shot.ts +1 -1
  74. package/src/cli/earnings-calendar.ts +4 -4
  75. package/src/cli/entry.ts +18 -1
  76. package/src/cli/errors.ts +20 -2
  77. package/src/cli/exit-codes.ts +1 -1
  78. package/src/cli/export-source.ts +10 -4
  79. package/src/cli/freshness.ts +2 -8
  80. package/src/cli/fx-forward.ts +130 -0
  81. package/src/cli/fx-pair.ts +10 -9
  82. package/src/cli/glossary.ts +64 -20
  83. package/src/cli/help.ts +19 -13
  84. package/src/cli/history-export.ts +126 -0
  85. package/src/cli/history-rows.ts +196 -43
  86. package/src/cli/index-roots.ts +5 -45
  87. package/src/cli/index.ts +24 -18
  88. package/src/cli/known-gaps.ts +118 -25
  89. package/src/cli/listing-arg.ts +300 -41
  90. package/src/cli/name-entries.ts +30 -18
  91. package/src/cli/native-smoke.ts +2 -0
  92. package/src/cli/not-a-ticker.ts +19 -9
  93. package/src/cli/opentui-libc.ts +5 -0
  94. package/src/cli/options.ts +12 -0
  95. package/src/cli/pane-functions/capabilities.ts +75 -20
  96. package/src/cli/pane-functions/catalog.ts +24 -23
  97. package/src/cli/pane-functions/discovery.ts +1 -1
  98. package/src/cli/pane-functions/dom.ts +10 -7
  99. package/src/cli/pane-functions/financial-ratio-shot.ts +2 -2
  100. package/src/cli/pane-functions/freshness.ts +174 -23
  101. package/src/cli/pane-functions/function-help.ts +66 -27
  102. package/src/cli/pane-functions/headless.ts +24 -11
  103. package/src/cli/pane-functions/index.ts +18 -16
  104. package/src/cli/pane-functions/options.ts +22 -2
  105. package/src/cli/pane-functions/report-notices.ts +12 -4
  106. package/src/cli/pane-functions/report.ts +5 -5
  107. package/src/cli/pane-functions/resolver.ts +47 -10
  108. package/src/cli/pane-functions/screenshot-assessment.ts +322 -0
  109. package/src/cli/pane-functions/screenshot-bridge.ts +152 -0
  110. package/src/cli/pane-functions/screenshot-chart-evidence.ts +396 -0
  111. package/src/cli/pane-functions/screenshot-data-evidence.ts +383 -0
  112. package/src/cli/pane-functions/screenshot-evidence.ts +1 -1
  113. package/src/cli/pane-functions/screenshot-payload.ts +453 -0
  114. package/src/cli/pane-functions/screenshot-render.ts +316 -0
  115. package/src/cli/pane-functions/screenshot-types.ts +162 -0
  116. package/src/cli/pane-functions/shot-options.ts +8 -3
  117. package/src/cli/peso-dollar-rates.ts +79 -0
  118. package/src/cli/quote-answer.ts +38 -3
  119. package/src/cli/report-tables.ts +61 -16
  120. package/src/cli/restore-plugins.ts +29 -14
  121. package/src/cli/result.ts +111 -22
  122. package/src/cli/series-search.ts +5 -5
  123. package/src/cli/statement-filings.ts +19 -0
  124. package/src/cli/suffixed-listing-rows.ts +49 -0
  125. package/src/cli/symbol-args.ts +50 -15
  126. package/src/cli/symbol-cells.ts +120 -0
  127. package/src/cli/symbol-list.ts +198 -68
  128. package/src/cli/symbol-rows.ts +131 -25
  129. package/src/cli/ticker-resolution.ts +108 -11
  130. package/src/cli/treasury-yields.ts +5 -5
  131. package/src/cli/types.ts +2 -0
  132. package/src/cli/uncovered-instrument.ts +3 -3
  133. package/src/cli/unknown-command.ts +6 -6
  134. package/src/components/chart/composite/chart-layout.ts +131 -0
  135. package/src/components/chart/composite/composite-chart.tsx +373 -16
  136. package/src/components/chart/composite/interactions.ts +7 -2
  137. package/src/components/chart/composite/legend.tsx +75 -3
  138. package/src/components/chart/composite/levels.ts +5 -0
  139. package/src/components/chart/composite/panel-gestures.ts +41 -0
  140. package/src/components/chart/composite/panel-labels.ts +2 -1
  141. package/src/components/chart/composite/panel-surface.tsx +305 -11
  142. package/src/components/chart/composite/price-axis-labels.tsx +27 -3
  143. package/src/components/chart/composite/rasterizer.ts +44 -19
  144. package/src/components/chart/composite/scene.ts +16 -4
  145. package/src/components/chart/composite/text-renderer.ts +48 -21
  146. package/src/components/chart/composite/toolbar.tsx +52 -5
  147. package/src/components/chart/composite/types.ts +13 -0
  148. package/src/components/chart/composite/use-composite-chart-keyboard.ts +120 -13
  149. package/src/components/chart/composite/use-composite-value-scales.ts +44 -0
  150. package/src/components/chart/composite/use-composite-viewport.ts +12 -3
  151. package/src/components/chart/composite/value-scale.ts +149 -0
  152. package/src/components/chart/composite/volume-profile-paint.ts +6 -3
  153. package/src/components/chart/core/pointer.ts +2 -0
  154. package/src/components/chart-table/index.ts +2 -0
  155. package/src/components/chart-table/read.tsx +74 -0
  156. package/src/components/command-bar/commands/collection-list.ts +41 -19
  157. package/src/components/command-bar/commands/collection.ts +9 -3
  158. package/src/components/command-bar/commands/direct/index.ts +1 -1
  159. package/src/components/command-bar/commands/direct/runtime.ts +3 -2
  160. package/src/components/command-bar/pane-templates/items.ts +59 -6
  161. package/src/components/command-bar/pane-templates/workflow.ts +10 -1
  162. package/src/components/command-bar/routes/root/plugin-install.ts +1 -1
  163. package/src/components/command-bar/routes/root/provider-search.ts +42 -11
  164. package/src/components/command-bar/routes/root/results.ts +18 -4
  165. package/src/components/command-bar/routes/root/runtime.ts +15 -3
  166. package/src/components/command-bar/routes/root/search-providers.ts +25 -2
  167. package/src/components/command-bar/routes/root/selection.ts +6 -1
  168. package/src/components/command-bar/routes/root/shortcut-feedback.ts +4 -1
  169. package/src/components/command-bar/routes/root/shortcuts.ts +30 -3
  170. package/src/components/command-bar/routes/ticker-search/results.ts +73 -4
  171. package/src/components/command-bar/selection-runtime.ts +50 -10
  172. package/src/components/command-bar/surface/index.tsx +24 -2
  173. package/src/components/command-bar/view-model.ts +7 -0
  174. package/src/components/command-bar/workflow/broker.ts +2 -2
  175. package/src/components/command-bar/workflow/collection-actions.ts +46 -7
  176. package/src/components/command-bar/workflow/collection-ticker.ts +32 -4
  177. package/src/components/command-bar/workflow/fields.ts +8 -2
  178. package/src/components/command-bar/workflow/ops.ts +18 -4
  179. package/src/components/command-bar/workflow/portfolio-position.ts +53 -4
  180. package/src/components/command-bar/workflow/submit.ts +3 -2
  181. package/src/components/command-bar/workflow/tickers.ts +5 -1
  182. package/src/components/company-logo.tsx +39 -0
  183. package/src/components/data-table/sections.ts +4 -2
  184. package/src/components/form-modal/confirm.tsx +2 -1
  185. package/src/components/form-modal/request.ts +5 -0
  186. package/src/components/form-modal/routes.ts +4 -1
  187. package/src/components/index.ts +12 -6
  188. package/src/components/layout/header.tsx +7 -6
  189. package/src/components/layout/market-summary.ts +9 -6
  190. package/src/components/layout/pane/capture-status.ts +1 -1
  191. package/src/components/layout/pane/footer/model.ts +11 -5
  192. package/src/components/layout/shell/chrome.ts +19 -6
  193. package/src/components/layout/shell/index.tsx +2 -1
  194. package/src/components/layout/shell/pane/layers.tsx +19 -1
  195. package/src/components/layout/status-bar.tsx +2 -2
  196. package/src/components/market-board/index.tsx +11 -3
  197. package/src/components/onboarding/onboarding-wizard.tsx +1 -0
  198. package/src/components/onboarding/portfolio-step/broker-setup-panel.tsx +2 -2
  199. package/src/components/onboarding/wizard-broker-sync.ts +4 -1
  200. package/src/components/pane-settings-dialog/desktop.tsx +20 -7
  201. package/src/components/pane-settings-dialog/tui.tsx +17 -9
  202. package/src/components/pane-settings-dialog/value.ts +8 -1
  203. package/src/components/pane-settings-dialog.tsx +44 -13
  204. package/src/components/sign-in-code-panel.tsx +27 -19
  205. package/src/components/ui/column-grid.tsx +48 -4
  206. package/src/components/ui/country-flag-art.tsx +180 -0
  207. package/src/components/ui/country-flag.tsx +118 -12
  208. package/src/components/ui/data-table/opentui/index.tsx +61 -2
  209. package/src/components/ui/data-table/opentui/model.ts +109 -2
  210. package/src/components/ui/data-table/types.ts +1 -1
  211. package/src/components/ui/display.tsx +5 -1
  212. package/src/components/ui/index.ts +3 -1
  213. package/src/components/ui/logo-mark.tsx +11 -2
  214. package/src/components/ui/query-bar.tsx +1 -1
  215. package/src/components/ui/row-notes.ts +79 -0
  216. package/src/core/state/app/layout.ts +4 -4
  217. package/src/data/cached-query.ts +8 -1
  218. package/src/data/config/chart-settings.ts +3 -3
  219. package/src/data/config/home.ts +10 -2
  220. package/src/data/config/layout.ts +4 -1
  221. package/src/data/config/store/node.ts +4 -0
  222. package/src/data/config/store/normalize.ts +13 -3
  223. package/src/data/config/store/portfolio-as-of-column.ts +2 -2
  224. package/src/data/json-storage.ts +2 -0
  225. package/src/data/saved-copies.ts +84 -0
  226. package/src/docs/snapshot.json +65 -32
  227. package/src/i18n/es.ts +29 -12
  228. package/src/i18n/ja.ts +29 -12
  229. package/src/i18n/ko.ts +29 -12
  230. package/src/i18n/zh-cn.ts +29 -12
  231. package/src/i18n/zh-tw.ts +29 -12
  232. package/src/layout/desks.ts +1 -1
  233. package/src/layout/launch-layout.ts +1 -1
  234. package/src/layout/pane-manager/floating-actions.ts +5 -3
  235. package/src/layout/pane-manager/floating.ts +43 -1
  236. package/src/layout/pane-manager/index.ts +2 -0
  237. package/src/layout/selected-ticker.ts +74 -0
  238. package/src/market-data/depositary-pair.ts +251 -0
  239. package/src/market-data/futures-board.ts +1 -1
  240. package/src/market-data/futures-contract.ts +124 -40
  241. package/src/market-data/fx-closes.ts +17 -2
  242. package/src/market-data/hooks.tsx +19 -11
  243. package/src/market-data/market/change-basis.ts +49 -7
  244. package/src/market-data/market/freshness.ts +34 -5
  245. package/src/market-data/market/period-return.ts +163 -0
  246. package/src/market-data/market/trading-sessions.ts +13 -0
  247. package/src/market-data/market/year-to-date.ts +8 -13
  248. package/src/market-data/performance.ts +20 -14
  249. package/src/market-data/perpetual-premium.ts +32 -0
  250. package/src/market-data/published-apac-sessions.ts +2 -1
  251. package/src/market-data/published-futures-sessions.ts +69 -0
  252. package/src/market-data/quotes/contributions.ts +5 -1
  253. package/src/market-data/quotes/freshness.ts +42 -0
  254. package/src/market-data/quotes/intraday-bar.ts +37 -0
  255. package/src/market-data/quotes/regular-session-valuation.ts +13 -8
  256. package/src/market-data/quotes/resolution.ts +4 -2
  257. package/src/market-data/tax-equivalent.ts +1 -1
  258. package/src/market-data/ticker-price-returns.ts +3 -1
  259. package/src/news/aggregator.ts +5 -1
  260. package/src/news/news-model.ts +4 -0
  261. package/src/news/types.ts +11 -0
  262. package/src/notifications/app-notifier.ts +1 -1
  263. package/src/plugins/auto-update.ts +2 -2
  264. package/src/plugins/builtin/account-management/index.tsx +1 -0
  265. package/src/plugins/builtin/account-management/pane.tsx +9 -8
  266. package/src/plugins/builtin/alerts/alert-engine.ts +29 -19
  267. package/src/plugins/builtin/alerts/calendar-events.ts +378 -0
  268. package/src/plugins/builtin/alerts/cli.ts +485 -76
  269. package/src/plugins/builtin/alerts/command.ts +5 -10
  270. package/src/plugins/builtin/alerts/event-rows.ts +9 -5
  271. package/src/plugins/builtin/alerts/events-pane.tsx +71 -56
  272. package/src/plugins/builtin/alerts/events.ts +107 -5
  273. package/src/plugins/builtin/alerts/fired-log.ts +78 -0
  274. package/src/plugins/builtin/alerts/format.ts +2 -1
  275. package/src/plugins/builtin/alerts/headless.ts +100 -39
  276. package/src/plugins/builtin/alerts/history-pane.tsx +105 -62
  277. package/src/plugins/builtin/alerts/history-rows.ts +89 -0
  278. package/src/plugins/builtin/alerts/index.tsx +45 -18
  279. package/src/plugins/builtin/alerts/iv-level.ts +365 -0
  280. package/src/plugins/builtin/alerts/levels.ts +3 -3
  281. package/src/plugins/builtin/alerts/pane.tsx +97 -29
  282. package/src/plugins/builtin/alerts/price.ts +35 -0
  283. package/src/plugins/builtin/alerts/quotes.ts +24 -0
  284. package/src/plugins/builtin/alerts/research-builder.ts +84 -11
  285. package/src/plugins/builtin/alerts/research-rules.ts +76 -3
  286. package/src/plugins/builtin/alerts/scheduled-check.ts +206 -32
  287. package/src/plugins/builtin/alerts/scheduled-sources.ts +26 -3
  288. package/src/plugins/builtin/alerts/scheduled.ts +188 -29
  289. package/src/plugins/builtin/alerts/storage.ts +13 -10
  290. package/src/plugins/builtin/alerts/targets.ts +12 -3
  291. package/src/plugins/builtin/analytics/index.tsx +8 -2
  292. package/src/plugins/builtin/analytics/metrics.ts +1 -1
  293. package/src/plugins/builtin/analytics/risk-book.ts +215 -0
  294. package/src/plugins/builtin/analytics/risk-client.ts +13 -6
  295. package/src/plugins/builtin/analytics/risk-headless.ts +55 -21
  296. package/src/plugins/builtin/analytics/risk-math.ts +6 -3
  297. package/src/plugins/builtin/analytics/risk-model.ts +297 -104
  298. package/src/plugins/builtin/analytics/risk-options.ts +17 -2
  299. package/src/plugins/builtin/analytics/risk-pane.tsx +97 -36
  300. package/src/plugins/builtin/attention/pane.tsx +6 -2
  301. package/src/plugins/builtin/awards/headless.ts +7 -3
  302. package/src/plugins/builtin/awards/model.ts +18 -0
  303. package/src/plugins/builtin/awards/pane.tsx +6 -3
  304. package/src/plugins/builtin/backtest/headless.ts +3 -3
  305. package/src/plugins/builtin/backtest/rules.ts +41 -5
  306. package/src/plugins/builtin/broker-manager/add-flow.tsx +12 -7
  307. package/src/plugins/builtin/broker-manager/detail.tsx +47 -19
  308. package/src/plugins/builtin/broker-manager/footer.ts +27 -11
  309. package/src/plugins/builtin/broker-manager/index.tsx +21 -12
  310. package/src/plugins/builtin/broker-manager/keyboard.ts +1 -1
  311. package/src/plugins/builtin/broker-manager/model.ts +12 -2
  312. package/src/plugins/builtin/broker-manager/pane-actions.tsx +183 -57
  313. package/src/plugins/builtin/broker-manager/table.ts +28 -12
  314. package/src/plugins/builtin/broker-trading/account-picker.tsx +2 -1
  315. package/src/plugins/builtin/broker-trading/chart-levels.ts +82 -13
  316. package/src/plugins/builtin/broker-trading/controller.ts +45 -13
  317. package/src/plugins/builtin/broker-trading/dock.tsx +22 -4
  318. package/src/plugins/builtin/broker-trading/headless.ts +2 -1
  319. package/src/plugins/builtin/broker-trading/index.tsx +7 -1
  320. package/src/plugins/builtin/broker-trading/linked-orders.ts +148 -0
  321. package/src/plugins/builtin/broker-trading/order-feed.ts +75 -7
  322. package/src/plugins/builtin/broker-trading/orders.tsx +109 -31
  323. package/src/plugins/builtin/broker-trading/overview-orders.tsx +9 -3
  324. package/src/plugins/builtin/broker-trading/pane-model.ts +30 -2
  325. package/src/plugins/builtin/broker-trading/pane.tsx +110 -23
  326. package/src/plugins/builtin/broker-trading/ticket-parts.tsx +36 -7
  327. package/src/plugins/builtin/broker-trading/ticket.tsx +112 -31
  328. package/src/plugins/builtin/buildout/cells.tsx +4 -0
  329. package/src/plugins/builtin/buildout/detail/index.tsx +5 -1
  330. package/src/plugins/builtin/buildout/detail/ui.tsx +7 -4
  331. package/src/plugins/builtin/buildout/pane/index.tsx +25 -12
  332. package/src/plugins/builtin/buildout/pane/status.tsx +0 -4
  333. package/src/plugins/builtin/builtin-plugin-meta.ts +1 -1
  334. package/src/plugins/builtin/catalysts/detail.tsx +3 -2
  335. package/src/plugins/builtin/catalysts/index.tsx +1 -1
  336. package/src/plugins/builtin/catalysts/model.ts +49 -4
  337. package/src/plugins/builtin/catalysts/pane.tsx +6 -8
  338. package/src/plugins/builtin/central-bank-rates/client.ts +5 -0
  339. package/src/plugins/builtin/central-bank-rates/headless.ts +36 -10
  340. package/src/plugins/builtin/central-bank-rates/model.ts +33 -8
  341. package/src/plugins/builtin/changelog/index.tsx +1 -0
  342. package/src/plugins/builtin/chart-composer/catalog-inventory.ts +1 -0
  343. package/src/plugins/builtin/chart-composer/chart-spec-edit.ts +2 -1
  344. package/src/plugins/builtin/chart-composer/chart-spec.ts +7 -0
  345. package/src/plugins/builtin/chart-composer/cli-options.ts +2 -5
  346. package/src/plugins/builtin/chart-composer/data-catalog-pane.tsx +2 -1
  347. package/src/plugins/builtin/chart-composer/editor/controller.ts +2 -0
  348. package/src/plugins/builtin/chart-composer/editor.tsx +4 -1
  349. package/src/plugins/builtin/chart-composer/headless-schema.ts +28 -26
  350. package/src/plugins/builtin/chart-composer/headless.ts +253 -35
  351. package/src/plugins/builtin/chart-composer/index.tsx +12 -2
  352. package/src/plugins/builtin/chart-composer/leverage-overlay.ts +142 -0
  353. package/src/plugins/builtin/chart-composer/pane.tsx +127 -28
  354. package/src/plugins/builtin/chart-composer/series-catalog.ts +1 -0
  355. package/src/plugins/builtin/chart-composer/series-expression.ts +65 -6
  356. package/src/plugins/builtin/chart-composer/session-history.ts +15 -21
  357. package/src/plugins/builtin/chart-composer/session-range.ts +4 -2
  358. package/src/plugins/builtin/chart-composer/settings.ts +31 -19
  359. package/src/plugins/builtin/chart-composer/use-series-catalog.ts +5 -6
  360. package/src/plugins/builtin/chart-composer/viewport-labels.ts +18 -8
  361. package/src/plugins/builtin/chat/attachments/model.ts +3 -1
  362. package/src/plugins/builtin/chat/content/index.tsx +1 -1
  363. package/src/plugins/builtin/chat/pane-links/open.ts +1 -1
  364. package/src/plugins/builtin/chat/people.ts +1 -1
  365. package/src/plugins/builtin/clinical-trials/client.ts +5 -2
  366. package/src/plugins/builtin/clinical-trials/model.ts +13 -4
  367. package/src/plugins/builtin/clinical-trials/pane.tsx +32 -12
  368. package/src/plugins/builtin/clinical-trials/ticker-sponsor.ts +17 -0
  369. package/src/plugins/builtin/cloud/askg/controller.ts +1 -1
  370. package/src/plugins/builtin/cloud/askg/lock-note.ts +1 -1
  371. package/src/plugins/builtin/cloud/askg/tool-display.ts +1 -1
  372. package/src/plugins/builtin/cloud/auth-commands.ts +3 -3
  373. package/src/plugins/builtin/cloud/team/pane-sections.tsx +105 -47
  374. package/src/plugins/builtin/cloud/team/pane-ui.tsx +42 -4
  375. package/src/plugins/builtin/cloud/team/pane.tsx +204 -64
  376. package/src/plugins/builtin/cloud/thesis/store.ts +45 -22
  377. package/src/plugins/builtin/cloud-tweets/registration.ts +1 -0
  378. package/src/plugins/builtin/commodities-energy/index.tsx +29 -2
  379. package/src/plugins/builtin/commodities-energy/view-state.ts +2 -0
  380. package/src/plugins/builtin/commodity-balances/pane.tsx +11 -4
  381. package/src/plugins/builtin/company-attention/app-rank.tsx +7 -5
  382. package/src/plugins/builtin/company-attention/building-model.ts +222 -0
  383. package/src/plugins/builtin/company-attention/building.tsx +172 -0
  384. package/src/plugins/builtin/company-attention/client.ts +117 -1
  385. package/src/plugins/builtin/company-attention/evidence.ts +16 -3
  386. package/src/plugins/builtin/company-attention/headless.ts +101 -5
  387. package/src/plugins/builtin/company-attention/index.tsx +6 -3
  388. package/src/plugins/builtin/company-attention/model.ts +33 -7
  389. package/src/plugins/builtin/company-attention/moves-model.ts +253 -0
  390. package/src/plugins/builtin/company-attention/moves.tsx +159 -0
  391. package/src/plugins/builtin/company-attention/pane.tsx +79 -23
  392. package/src/plugins/builtin/company-attention/signals-model.ts +229 -0
  393. package/src/plugins/builtin/company-attention/signals.tsx +160 -0
  394. package/src/plugins/builtin/company-kpis/headless.ts +3 -2
  395. package/src/plugins/builtin/company-kpis/model.ts +2 -2
  396. package/src/plugins/builtin/company-kpis/pane.tsx +1 -1
  397. package/src/plugins/builtin/composite-plugins.ts +2 -1
  398. package/src/plugins/builtin/congress-trades/headless.ts +1 -1
  399. package/src/plugins/builtin/connections/index.ts +1 -0
  400. package/src/plugins/builtin/correlation/headless-schema.ts +3 -2
  401. package/src/plugins/builtin/correlation/headless.ts +5 -3
  402. package/src/plugins/builtin/cot/headless.ts +28 -6
  403. package/src/plugins/builtin/cot/model.ts +12 -0
  404. package/src/plugins/builtin/cot/pane.tsx +3 -2
  405. package/src/plugins/builtin/cpi/headless.ts +5 -1
  406. package/src/plugins/builtin/cpi/pane.tsx +11 -9
  407. package/src/plugins/builtin/credit-boards/model.ts +2 -0
  408. package/src/plugins/builtin/credit-documents/headless.ts +1 -1
  409. package/src/plugins/builtin/crypto-board/client.ts +86 -0
  410. package/src/plugins/builtin/crypto-board/defi-view.tsx +218 -0
  411. package/src/plugins/builtin/crypto-board/defi.ts +239 -0
  412. package/src/plugins/builtin/crypto-board/headless.ts +117 -6
  413. package/src/plugins/builtin/crypto-board/index.tsx +8 -3
  414. package/src/plugins/builtin/crypto-board/model.ts +40 -8
  415. package/src/plugins/builtin/crypto-board/pane.tsx +55 -21
  416. package/src/plugins/builtin/crypto-board/series.ts +19 -1
  417. package/src/plugins/builtin/crypto-etf-flows/client.ts +60 -0
  418. package/src/plugins/builtin/crypto-etf-flows/headless.ts +132 -0
  419. package/src/plugins/builtin/crypto-etf-flows/index.tsx +44 -0
  420. package/src/plugins/builtin/crypto-etf-flows/model.ts +121 -0
  421. package/src/plugins/builtin/crypto-etf-flows/pane.tsx +193 -0
  422. package/src/plugins/builtin/debug/index.tsx +1 -0
  423. package/src/plugins/builtin/dividend-yield/index.tsx +1 -1
  424. package/src/plugins/builtin/docs/index.tsx +1 -1
  425. package/src/plugins/builtin/docs/pane.tsx +2 -2
  426. package/src/plugins/builtin/docs/targets.ts +1 -1
  427. package/src/plugins/builtin/doe/client.ts +5 -1
  428. package/src/plugins/builtin/doe/headless.ts +12 -6
  429. package/src/plugins/builtin/doe/model.ts +43 -6
  430. package/src/plugins/builtin/doe/pane.tsx +18 -11
  431. package/src/plugins/builtin/earnings/board-model.ts +13 -6
  432. package/src/plugins/builtin/earnings/board-table.ts +4 -1
  433. package/src/plugins/builtin/earnings/board.tsx +253 -50
  434. package/src/plugins/builtin/earnings/calendar-model.ts +188 -0
  435. package/src/plugins/builtin/earnings/calendar.tsx +338 -0
  436. package/src/plugins/builtin/earnings/client.ts +4 -3
  437. package/src/plugins/builtin/earnings/headless.ts +53 -15
  438. package/src/plugins/builtin/earnings/history-model.ts +53 -36
  439. package/src/plugins/builtin/earnings/index.tsx +15 -22
  440. package/src/plugins/builtin/earnings/model.ts +17 -12
  441. package/src/plugins/builtin/earnings/scope.ts +89 -0
  442. package/src/plugins/builtin/earnings-calls/calendar.tsx +310 -0
  443. package/src/plugins/builtin/earnings-calls/data.ts +146 -2
  444. package/src/plugins/builtin/earnings-calls/headless.ts +151 -9
  445. package/src/plugins/builtin/earnings-calls/index.tsx +3 -3
  446. package/src/plugins/builtin/earnings-calls/lock-note.ts +1 -1
  447. package/src/plugins/builtin/earnings-calls/pane.tsx +149 -31
  448. package/src/plugins/builtin/earnings-calls/upcoming.ts +195 -0
  449. package/src/plugins/builtin/earnings-ripple/pane.tsx +10 -5
  450. package/src/plugins/builtin/econ/calendar-model.ts +132 -20
  451. package/src/plugins/builtin/econ/detail-view.tsx +48 -10
  452. package/src/plugins/builtin/econ/fred-catalog.ts +23 -6
  453. package/src/plugins/builtin/econ/fred-series-map.ts +4 -0
  454. package/src/plugins/builtin/econ/index.tsx +112 -25
  455. package/src/plugins/builtin/econ/print-watch.ts +2 -1
  456. package/src/plugins/builtin/econ/types.ts +32 -1
  457. package/src/plugins/builtin/econ-statistics/client.ts +16 -3
  458. package/src/plugins/builtin/econ-statistics/defs.ts +4 -0
  459. package/src/plugins/builtin/econ-statistics/detail.tsx +2 -2
  460. package/src/plugins/builtin/econ-statistics/headless.ts +13 -2
  461. package/src/plugins/builtin/econ-statistics/index.tsx +3 -3
  462. package/src/plugins/builtin/econ-statistics/pane.tsx +2 -1
  463. package/src/plugins/builtin/econ-statistics/stats.ts +103 -0
  464. package/src/plugins/builtin/econ-statistics/view.ts +16 -1
  465. package/src/plugins/builtin/equity-screener/client.ts +21 -3
  466. package/src/plugins/builtin/equity-screener/headless.ts +68 -6
  467. package/src/plugins/builtin/equity-screener/live.ts +1 -1
  468. package/src/plugins/builtin/equity-screener/model.ts +6 -0
  469. package/src/plugins/builtin/equity-screener/pane.tsx +45 -10
  470. package/src/plugins/builtin/equity-screener/screen-check.ts +90 -0
  471. package/src/plugins/builtin/equity-screener/ticker-check.tsx +148 -0
  472. package/src/plugins/builtin/estimate-revisions/headless.ts +3 -1
  473. package/src/plugins/builtin/estimate-revisions/lock-note.ts +3 -3
  474. package/src/plugins/builtin/estimate-revisions/model.ts +8 -10
  475. package/src/plugins/builtin/exposure/headless.ts +51 -6
  476. package/src/plugins/builtin/exposure/index.tsx +28 -2
  477. package/src/plugins/builtin/exposure/model.ts +7 -0
  478. package/src/plugins/builtin/exposure/pane.tsx +6 -1
  479. package/src/plugins/builtin/fear-greed/index.tsx +1 -1
  480. package/src/plugins/builtin/filing-events/index.tsx +1 -1
  481. package/src/plugins/builtin/futures/model.ts +10 -9
  482. package/src/plugins/builtin/futures/returns.ts +8 -36
  483. package/src/plugins/builtin/futures/table.tsx +1 -1
  484. package/src/plugins/builtin/futures-curve/client.ts +40 -9
  485. package/src/plugins/builtin/futures-curve/headless.ts +39 -17
  486. package/src/plugins/builtin/futures-curve/model.ts +258 -69
  487. package/src/plugins/builtin/futures-curve/pane.tsx +46 -17
  488. package/src/plugins/builtin/fx-matrix/client.ts +15 -8
  489. package/src/plugins/builtin/fx-matrix/headless.ts +32 -14
  490. package/src/plugins/builtin/fx-matrix/index.tsx +13 -11
  491. package/src/plugins/builtin/fx-matrix/live-legs.ts +22 -0
  492. package/src/plugins/builtin/fx-matrix/settings.ts +2 -1
  493. package/src/plugins/builtin/gpu/headless.ts +9 -4
  494. package/src/plugins/builtin/help/index.tsx +13 -3
  495. package/src/plugins/builtin/holders/beneficial-model.ts +8 -11
  496. package/src/plugins/builtin/holders/beneficial-report.ts +6 -5
  497. package/src/plugins/builtin/holders/beneficial-view.tsx +7 -3
  498. package/src/plugins/builtin/holders/client.ts +13 -1
  499. package/src/plugins/builtin/holders/format.ts +28 -17
  500. package/src/plugins/builtin/holders/headless.ts +46 -7
  501. package/src/plugins/builtin/holders/index-holders.ts +264 -0
  502. package/src/plugins/builtin/holders/pane.tsx +79 -15
  503. package/src/plugins/builtin/holders/report-rows.ts +35 -7
  504. package/src/plugins/builtin/holders/table-model.ts +2 -1
  505. package/src/plugins/builtin/holders/treemap.tsx +2 -2
  506. package/src/plugins/builtin/insider/headless.ts +1 -1
  507. package/src/plugins/builtin/insider/signals-client.ts +1 -1
  508. package/src/plugins/builtin/insider/signals.tsx +1 -1
  509. package/src/plugins/builtin/ipo-calendar/pane.tsx +7 -4
  510. package/src/plugins/builtin/iv-history/client.ts +20 -0
  511. package/src/plugins/builtin/iv-history/headless.ts +4 -4
  512. package/src/plugins/builtin/iv-history/index.tsx +1 -1
  513. package/src/plugins/builtin/iv-history/model.ts +13 -4
  514. package/src/plugins/builtin/iv-history/series.ts +3 -1
  515. package/src/plugins/builtin/jobs/lock-note.ts +1 -1
  516. package/src/plugins/builtin/jobs/model.ts +4 -15
  517. package/src/plugins/builtin/jobs/pane.tsx +7 -5
  518. package/src/plugins/builtin/jobs/share-bars.tsx +11 -5
  519. package/src/plugins/builtin/jodi/pane.tsx +10 -4
  520. package/src/plugins/builtin/layout-manager/index.tsx +1 -0
  521. package/src/plugins/builtin/macro-day/headless.ts +20 -7
  522. package/src/plugins/builtin/macro-day/index.tsx +3 -2
  523. package/src/plugins/builtin/macro-day/model.ts +29 -8
  524. package/src/plugins/builtin/macro-day/pane.tsx +46 -10
  525. package/src/plugins/builtin/macro-day/releases.ts +55 -13
  526. package/src/plugins/builtin/market-heatmap/data.ts +9 -2
  527. package/src/plugins/builtin/market-heatmap/evidence.ts +1 -1
  528. package/src/plugins/builtin/market-heatmap/headless.ts +9 -6
  529. package/src/plugins/builtin/market-heatmap/index.tsx +3 -3
  530. package/src/plugins/builtin/market-heatmap/model.ts +10 -7
  531. package/src/plugins/builtin/market-movers/client.ts +33 -19
  532. package/src/plugins/builtin/market-movers/headless.ts +8 -2
  533. package/src/plugins/builtin/market-movers/index.tsx +16 -10
  534. package/src/plugins/builtin/market-movers/screener.ts +29 -8
  535. package/src/plugins/builtin/market-movers/session-body.tsx +4 -2
  536. package/src/plugins/builtin/market-movers/session-table.ts +4 -2
  537. package/src/plugins/builtin/market-movers/table.ts +4 -1
  538. package/src/plugins/builtin/market-valuation/headless.ts +2 -0
  539. package/src/plugins/builtin/market-valuation/view.ts +5 -0
  540. package/src/plugins/builtin/members/headless.ts +6 -5
  541. package/src/plugins/builtin/members/pane.tsx +11 -4
  542. package/src/plugins/builtin/mna/client.ts +1 -0
  543. package/src/plugins/builtin/mna/detail.tsx +20 -32
  544. package/src/plugins/builtin/mna/distress/detail.tsx +16 -4
  545. package/src/plugins/builtin/mna/distress/model.ts +3 -2
  546. package/src/plugins/builtin/mna/distress/pane.tsx +7 -4
  547. package/src/plugins/builtin/mna/headless.ts +6 -13
  548. package/src/plugins/builtin/mna/model.ts +93 -15
  549. package/src/plugins/builtin/mna/pane.tsx +5 -4
  550. package/src/plugins/builtin/news/headless.ts +12 -6
  551. package/src/plugins/builtin/news/index.tsx +10 -1
  552. package/src/plugins/builtin/news/wire/index.tsx +3 -2
  553. package/src/plugins/builtin/news/wire/news/command-bar-search.ts +26 -10
  554. package/src/plugins/builtin/news/wire/news/query-presets.ts +6 -2
  555. package/src/plugins/builtin/news/wire/rss/cli.ts +3 -3
  556. package/src/plugins/builtin/notes/cli.ts +49 -14
  557. package/src/plugins/builtin/openfda/pane.tsx +1 -1
  558. package/src/plugins/builtin/options/carry.ts +2 -2
  559. package/src/plugins/builtin/options/index.tsx +1 -1
  560. package/src/plugins/builtin/options/view.tsx +10 -10
  561. package/src/plugins/builtin/options-calculator/headless.ts +46 -7
  562. package/src/plugins/builtin/options-scenario/client.ts +123 -28
  563. package/src/plugins/builtin/options-scenario/collar.ts +8 -6
  564. package/src/plugins/builtin/options-scenario/csp-screen-headless.ts +127 -0
  565. package/src/plugins/builtin/options-scenario/csp-screen-pane.tsx +165 -0
  566. package/src/plugins/builtin/options-scenario/csp-screen.ts +258 -0
  567. package/src/plugins/builtin/options-scenario/csp.ts +101 -21
  568. package/src/plugins/builtin/options-scenario/headless.ts +36 -15
  569. package/src/plugins/builtin/options-scenario/hedge.ts +20 -14
  570. package/src/plugins/builtin/options-scenario/index.tsx +28 -3
  571. package/src/plugins/builtin/options-scenario/model.ts +13 -0
  572. package/src/plugins/builtin/options-scenario/pane.tsx +9 -5
  573. package/src/plugins/builtin/perps/equity-row.tsx +11 -3
  574. package/src/plugins/builtin/perps/freshness.ts +8 -5
  575. package/src/plugins/builtin/perps/headless.ts +3 -1
  576. package/src/plugins/builtin/perps/list-perpetuals.ts +25 -4
  577. package/src/plugins/builtin/perps/live-rows.ts +161 -0
  578. package/src/plugins/builtin/perps/markets-section.tsx +154 -0
  579. package/src/plugins/builtin/perps/pane.tsx +36 -17
  580. package/src/plugins/builtin/perps/venue-markets.ts +96 -0
  581. package/src/plugins/builtin/plugin-marketplace/index.tsx +2 -1
  582. package/src/plugins/builtin/plugin-marketplace/pane.tsx +143 -59
  583. package/src/plugins/builtin/portfolio-list/cli/bulk-symbols.ts +72 -24
  584. package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +158 -141
  585. package/src/plugins/builtin/portfolio-list/cli/render.ts +49 -20
  586. package/src/plugins/builtin/portfolio-list/cli/shared.ts +3 -3
  587. package/src/plugins/builtin/portfolio-list/cli/watchlist-command.ts +29 -24
  588. package/src/plugins/builtin/portfolio-list/headless.ts +6 -3
  589. package/src/plugins/builtin/portfolio-list/income.ts +13 -2
  590. package/src/plugins/builtin/portfolio-list/index.tsx +9 -2
  591. package/src/plugins/builtin/portfolio-list/pane/index.tsx +21 -8
  592. package/src/plugins/builtin/portfolio-list/pane/purchase-date-fx.ts +46 -0
  593. package/src/plugins/builtin/portfolio-list/summary/live-accounts.ts +16 -9
  594. package/src/plugins/builtin/portfolio-list/summary/totals.ts +2 -15
  595. package/src/plugins/builtin/power/client.ts +4 -1
  596. package/src/plugins/builtin/power/evidence.ts +22 -7
  597. package/src/plugins/builtin/power/gas.tsx +5 -1
  598. package/src/plugins/builtin/power/pane.tsx +8 -1
  599. package/src/plugins/builtin/power/prices.tsx +10 -3
  600. package/src/plugins/builtin/research/analyst-headless.ts +25 -8
  601. package/src/plugins/builtin/research/analyst-model.ts +68 -3
  602. package/src/plugins/builtin/research/corporate-actions-pane.tsx +63 -14
  603. package/src/plugins/builtin/research/event-model.ts +3 -1
  604. package/src/plugins/builtin/research/event-sources.ts +12 -4
  605. package/src/plugins/builtin/research/index.tsx +2 -1
  606. package/src/plugins/builtin/research/relative-valuation-basis.ts +58 -0
  607. package/src/plugins/builtin/research/relative-valuation-columns.ts +31 -2
  608. package/src/plugins/builtin/research/relative-valuation-currency.ts +12 -5
  609. package/src/plugins/builtin/research/relative-valuation-headless.ts +84 -26
  610. package/src/plugins/builtin/research/relative-valuation-model.ts +88 -19
  611. package/src/plugins/builtin/research/relative-valuation-pane.tsx +76 -9
  612. package/src/plugins/builtin/research/relative-valuation-peers.ts +1 -1
  613. package/src/plugins/builtin/reverse-dcf/model.ts +6 -2
  614. package/src/plugins/builtin/risk-factors/index.tsx +2 -2
  615. package/src/plugins/builtin/scanner/lock-note.ts +1 -1
  616. package/src/plugins/builtin/sec/forms.ts +13 -0
  617. package/src/plugins/builtin/sec/fund-abroad.ts +32 -0
  618. package/src/plugins/builtin/sec/fund-facts.ts +68 -8
  619. package/src/plugins/builtin/sec/headless.ts +85 -8
  620. package/src/plugins/builtin/sec/index.tsx +58 -12
  621. package/src/plugins/builtin/sectors/client.ts +2 -1
  622. package/src/plugins/builtin/sectors/sector-model.ts +11 -15
  623. package/src/plugins/builtin/series-inventory.ts +2 -0
  624. package/src/plugins/builtin/shared/broker-reconnect.ts +107 -22
  625. package/src/plugins/builtin/shared/cloud-upgrade.ts +34 -6
  626. package/src/plugins/builtin/shared/earnings-calendar.ts +375 -0
  627. package/src/plugins/builtin/{earnings/estimate-basis.ts → shared/earnings-estimate-basis.ts} +1 -1
  628. package/src/plugins/builtin/shared/earnings-report.ts +3 -3
  629. package/src/plugins/builtin/shared/fx-rate-freshness.ts +23 -1
  630. package/src/plugins/builtin/shared/job-posting.ts +129 -0
  631. package/src/plugins/builtin/shared/pro-lock-note.ts +3 -3
  632. package/src/plugins/builtin/shared/report-freshness.ts +3 -0
  633. package/src/plugins/builtin/shared/research-trading.tsx +21 -0
  634. package/src/plugins/builtin/shared/series-cache.ts +2 -0
  635. package/src/plugins/builtin/shared/ticker-surface.ts +2 -1
  636. package/src/plugins/builtin/short-interest/client.ts +2 -0
  637. package/src/plugins/builtin/short-interest/headless.ts +41 -12
  638. package/src/plugins/builtin/short-interest/index.tsx +23 -1
  639. package/src/plugins/builtin/short-interest/model.ts +70 -19
  640. package/src/plugins/builtin/short-interest/pane.tsx +19 -2
  641. package/src/plugins/builtin/short-interest/publications-client.ts +82 -0
  642. package/src/plugins/builtin/short-interest/publications-headless.ts +29 -0
  643. package/src/plugins/builtin/short-interest/publications-model.ts +50 -0
  644. package/src/plugins/builtin/short-interest/publications-pane.tsx +66 -0
  645. package/src/plugins/builtin/short-interest/schedule.ts +35 -2
  646. package/src/plugins/builtin/short-interest/surface.tsx +11 -4
  647. package/src/plugins/builtin/short-interest/types.ts +9 -0
  648. package/src/plugins/builtin/short-interest/watch-client.ts +14 -8
  649. package/src/plugins/builtin/short-interest/watch-model.ts +12 -25
  650. package/src/plugins/builtin/short-interest/watch-pane.tsx +5 -1
  651. package/src/plugins/builtin/supply-chain/flow.tsx +33 -9
  652. package/src/plugins/builtin/supply-chain/model.ts +51 -3
  653. package/src/plugins/builtin/supply-chain/pane.tsx +78 -39
  654. package/src/plugins/builtin/supply-chain/row-evidence.tsx +1 -1
  655. package/src/plugins/builtin/themes/headless.ts +8 -5
  656. package/src/plugins/builtin/themes/model.ts +14 -4
  657. package/src/plugins/builtin/themes/pane.tsx +24 -5
  658. package/src/plugins/builtin/thirteenf/headless.ts +5 -5
  659. package/src/plugins/builtin/thirteenf/signals.ts +3 -1
  660. package/src/plugins/builtin/ticker-detail/adr-pair/headless.ts +123 -0
  661. package/src/plugins/builtin/ticker-detail/adr-pair/model.ts +132 -0
  662. package/src/plugins/builtin/ticker-detail/adr-pair/tab.tsx +87 -0
  663. package/src/plugins/builtin/ticker-detail/data-panes/historical-prices.tsx +40 -26
  664. package/src/plugins/builtin/ticker-detail/data-panes/history-bars.ts +8 -4
  665. package/src/plugins/builtin/ticker-detail/data-panes/returns-history.ts +67 -3
  666. package/src/plugins/builtin/ticker-detail/data-panes/returns-model.ts +112 -5
  667. package/src/plugins/builtin/ticker-detail/data-panes/returns-pane.tsx +17 -2
  668. package/src/plugins/builtin/ticker-detail/financials/aggregation.ts +21 -7
  669. package/src/plugins/builtin/ticker-detail/financials/model.ts +36 -1
  670. package/src/plugins/builtin/ticker-detail/financials/offerings.ts +56 -0
  671. package/src/plugins/builtin/ticker-detail/financials/ratios.ts +62 -13
  672. package/src/plugins/builtin/ticker-detail/financials/tab.tsx +30 -4
  673. package/src/plugins/builtin/ticker-detail/headless-schema.ts +14 -2
  674. package/src/plugins/builtin/ticker-detail/headless.ts +148 -35
  675. package/src/plugins/builtin/ticker-detail/index.tsx +37 -5
  676. package/src/plugins/builtin/ticker-detail/overview/model.ts +65 -10
  677. package/src/plugins/builtin/ticker-detail/overview/pane.tsx +9 -1
  678. package/src/plugins/builtin/ticker-detail/overview-tab.tsx +68 -11
  679. package/src/plugins/builtin/ticker-detail/pane.tsx +11 -0
  680. package/src/plugins/builtin/ticker-detail/quote-footer.ts +8 -3
  681. package/src/plugins/builtin/ticker-detail/research-tabs.ts +11 -0
  682. package/src/plugins/builtin/vol-surface/client.ts +5 -4
  683. package/src/plugins/builtin/vol-surface/headless.ts +12 -3
  684. package/src/plugins/builtin/vol-surface/model.ts +4 -2
  685. package/src/plugins/builtin/volatility/model.ts +5 -10
  686. package/src/plugins/builtin/world-venue-map/basemap-layer.tsx +4 -3
  687. package/src/plugins/builtin/world-venue-map/basemap.ts +3 -1
  688. package/src/plugins/builtin/world-venue-map/chokepoint-chart.ts +40 -0
  689. package/src/plugins/builtin/world-venue-map/evidence.ts +1 -1
  690. package/src/plugins/builtin/world-venue-map/geo-series.ts +90 -11
  691. package/src/plugins/builtin/world-venue-map/headless.ts +1 -1
  692. package/src/plugins/builtin/world-venue-map/index.ts +3 -26
  693. package/src/plugins/builtin/world-venue-map/layers.ts +1 -1
  694. package/src/plugins/builtin/world-venue-map/map.tsx +2 -1
  695. package/src/plugins/builtin/world-venue-map/pane.tsx +4 -2
  696. package/src/plugins/builtin/world-venue-map/venue-header.tsx +15 -4
  697. package/src/plugins/builtin/yield-curve/client.ts +25 -0
  698. package/src/plugins/builtin/yield-curve/curves.ts +7 -4
  699. package/src/plugins/builtin/yield-curve/headless.ts +38 -4
  700. package/src/plugins/builtin/yield-curve/history.ts +4 -3
  701. package/src/plugins/builtin/yield-curve/index.tsx +12 -6
  702. package/src/plugins/builtin/yield-curve/swaps-model.ts +93 -0
  703. package/src/plugins/builtin/yield-curve/swaps.tsx +99 -0
  704. package/src/plugins/bundle.ts +1 -1
  705. package/src/plugins/catalog-browser.ts +2 -1
  706. package/src/plugins/compat.ts +3 -3
  707. package/src/plugins/dependencies.ts +75 -14
  708. package/src/plugins/extracted-plugins.ts +132 -34
  709. package/src/plugins/host-link.ts +149 -34
  710. package/src/plugins/installer.ts +35 -10
  711. package/src/plugins/loader.ts +206 -38
  712. package/src/plugins/manager-node.ts +2 -2
  713. package/src/plugins/marketplace/deactivation.ts +22 -0
  714. package/src/plugins/marketplace/model.ts +2 -2
  715. package/src/plugins/marketplace/packs.ts +1 -1
  716. package/src/plugins/ownership.ts +1 -1
  717. package/src/plugins/peer-retry.ts +155 -0
  718. package/src/plugins/registry/contributions.ts +3 -1
  719. package/src/plugins/registry/index.ts +4 -3
  720. package/src/plugins/registry/plugin-state.ts +3 -0
  721. package/src/plugins/seed-notice.ts +20 -0
  722. package/src/plugins/shortcut-argument.ts +39 -0
  723. package/src/portfolio/allocation.ts +1 -1
  724. package/src/portfolio/collection-name.ts +31 -0
  725. package/src/portfolio/column-values.ts +10 -8
  726. package/src/portfolio/cost-fx.ts +296 -19
  727. package/src/portfolio/manual-lots.ts +75 -0
  728. package/src/portfolio/mutations.ts +60 -22
  729. package/src/portfolio/suffixed-listings.ts +209 -0
  730. package/src/portfolio/totals-currency.ts +24 -0
  731. package/src/public/__snapshots__/public-api.test.ts.snap +14 -0
  732. package/src/public/time-series.ts +11 -8
  733. package/src/remote/schema.ts +1 -1
  734. package/src/renderers/browser/config-host.ts +3 -0
  735. package/src/renderers/browser/main.tsx +23 -3
  736. package/src/renderers/dom/boot-frame-page.ts +187 -0
  737. package/src/renderers/dom/boot-frame.ts +237 -0
  738. package/src/renderers/dom/build-assets.ts +46 -8
  739. package/src/renderers/dom/dom-ui-host.tsx +4 -29
  740. package/src/renderers/dom/host/ascii-text.ts +16 -2
  741. package/src/renderers/dom/host/box.tsx +43 -2
  742. package/src/renderers/dom/host/chart-surface.tsx +2 -0
  743. package/src/renderers/dom/host/hls.chunk.ts +3 -0
  744. package/src/renderers/dom/host/image-surface.tsx +49 -0
  745. package/src/renderers/dom/host/media-surface.tsx +24 -18
  746. package/src/renderers/dom/host/mouse.ts +30 -0
  747. package/src/renderers/dom/host/size-observer.ts +1 -1
  748. package/src/renderers/dom/host/style.ts +1 -1
  749. package/src/renderers/dom/styles.css +76 -0
  750. package/src/renderers/dom/test-utils.tsx +2 -1
  751. package/src/renderers/electrobun/bun/application-menu/index.ts +3 -3
  752. package/src/renderers/electrobun/bun/desktop/backend-requests.ts +3 -0
  753. package/src/renderers/electrobun/bun/desktop/backend.ts +46 -3
  754. package/src/renderers/electrobun/bun/desktop/detached-windows.ts +1 -1
  755. package/src/renderers/electrobun/bun/desktop/host-requests.ts +9 -3
  756. package/src/renderers/electrobun/bun/desktop/initialization.ts +81 -18
  757. package/src/renderers/electrobun/bun/external-plugins.ts +29 -7
  758. package/src/renderers/electrobun/bun/index.ts +11 -1
  759. package/src/renderers/electrobun/bun/window/boot-frame.ts +67 -0
  760. package/src/renderers/electrobun/bun/window/create.ts +4 -1
  761. package/src/renderers/electrobun/shared/boot-frame.ts +7 -0
  762. package/src/renderers/electrobun/shared/protocol.ts +6 -1
  763. package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +1 -1
  764. package/src/renderers/electrobun/view/config-host.ts +3 -0
  765. package/src/renderers/electrobun/view/fatal-screen.tsx +1 -1
  766. package/src/renderers/electrobun/view/main.tsx +30 -4
  767. package/src/renderers/electrobun/view/news-source.ts +5 -5
  768. package/src/renderers/electrobun/view/remote/asset-data-client.ts +1 -1
  769. package/src/renderers/electrobun/view/ui-host.tsx +1 -1
  770. package/src/renderers/opentui/browser-open.ts +88 -0
  771. package/src/renderers/opentui/host.tsx +5 -14
  772. package/src/renderers/opentui/image/loader.ts +3 -2
  773. package/src/renderers/opentui/native-smoke.ts +10 -1
  774. package/src/renderers/opentui/pane-image/index.ts +2 -1
  775. package/src/renderers/opentui/render-lib.ts +253 -0
  776. package/src/renderers/opentui/render-timing-smoke.ts +1 -1
  777. package/src/renderers/opentui/start.tsx +1 -1
  778. package/src/renderers/share/layout-view.tsx +2 -2
  779. package/src/renderers/share/main.tsx +4 -4
  780. package/src/renderers/share/view.tsx +1 -1
  781. package/src/series/resolve.ts +22 -6
  782. package/src/series/standalone.ts +30 -2
  783. package/src/series/types.ts +8 -1
  784. package/src/shares/api.ts +4 -1
  785. package/src/shares/pane.ts +1 -1
  786. package/src/sources/gloomberb-cloud/fred-series.ts +46 -1
  787. package/src/sources/gloomberb-cloud/index.ts +32 -16
  788. package/src/sources/gloomberb-cloud/news.ts +39 -0
  789. package/src/sources/gloomberb-cloud/normalizers.ts +14 -1
  790. package/src/sources/gloomberb-cloud/perpetuals.ts +49 -1
  791. package/src/sources/listing-symbols.ts +37 -0
  792. package/src/sources/provider-errors.ts +16 -2
  793. package/src/sources/provider-router/financial-routes.ts +21 -3
  794. package/src/sources/provider-router/financials.ts +15 -2
  795. package/src/sources/provider-router/history.ts +30 -8
  796. package/src/sources/provider-router/primary.ts +1 -1
  797. package/src/state/app/bootstrap.ts +23 -0
  798. package/src/state/hooks/inline-tickers.ts +30 -5
  799. package/src/sync/controller.ts +1 -1
  800. package/src/sync/core-contributors.ts +46 -14
  801. package/src/team/collections-sync.ts +2 -1
  802. package/src/team/collections.ts +178 -17
  803. package/src/telemetry/crash-reports.ts +17 -4
  804. package/src/test-support/builtin-panes.ts +1 -1
  805. package/src/theme/colors.ts +3 -30
  806. package/src/theme/ui-tokens.ts +37 -1
  807. package/src/tickers/company-name-listing.ts +210 -33
  808. package/src/tickers/index-roots.ts +47 -0
  809. package/src/tickers/instrument-label.ts +5 -1
  810. package/src/tickers/metadata.ts +10 -0
  811. package/src/tickers/perpetual-listing.ts +5 -2
  812. package/src/tickers/search/home-listing.ts +75 -0
  813. package/src/tickers/search/index.ts +76 -27
  814. package/src/tickers/search/ranking.ts +54 -4
  815. package/src/tickers/search/upsert.ts +29 -0
  816. package/src/tickers/terminal-codes.ts +416 -40
  817. package/src/time-series/bar-aggregation.ts +243 -0
  818. package/src/time-series/base-series.ts +307 -0
  819. package/src/time-series/chart-bounds.ts +349 -0
  820. package/src/time-series/chart-seed.ts +142 -0
  821. package/src/time-series/economic.ts +5 -0
  822. package/src/time-series/fundamentals.ts +18 -3
  823. package/src/time-series/history-acquisition.ts +499 -0
  824. package/src/time-series/leverage.ts +100 -0
  825. package/src/time-series/market-resolution.ts +4 -2
  826. package/src/time-series/market.ts +2 -1
  827. package/src/time-series/price-comparison.ts +175 -30
  828. package/src/time-series/range.ts +9 -1
  829. package/src/time-series/resolution.ts +174 -16
  830. package/src/time-series/resolve-context.ts +157 -0
  831. package/src/time-series/resolve.ts +126 -1577
  832. package/src/time-series/series-name.ts +38 -0
  833. package/src/time-series/series-presentation.ts +208 -0
  834. package/src/time-series/spec.ts +11 -6
  835. package/src/time-series/studies.ts +109 -12
  836. package/src/time-series/tail-reconcile.ts +121 -0
  837. package/src/time-series/types.ts +29 -2
  838. package/src/time-series/use-chart-resolution.ts +4 -5
  839. package/src/types/broker.ts +10 -0
  840. package/src/types/config.ts +14 -0
  841. package/src/types/data-provider.ts +14 -0
  842. package/src/types/exchange-rate.ts +6 -0
  843. package/src/types/financials.ts +104 -7
  844. package/src/types/headless.ts +76 -6
  845. package/src/types/instrument.ts +3 -0
  846. package/src/types/plugin.ts +65 -8
  847. package/src/types/price-history.ts +2 -0
  848. package/src/types/ticker.ts +13 -0
  849. package/src/types/trading.ts +59 -1
  850. package/src/ui/ascii-font.ts +13 -1
  851. package/src/ui/host.tsx +6 -1
  852. package/src/updater/command-names.ts +175 -0
  853. package/src/updater/index.ts +10 -5
  854. package/src/utils/calendar-date.ts +32 -15
  855. package/src/utils/cash-runway.ts +241 -0
  856. package/src/utils/central-banks.ts +42 -0
  857. package/src/utils/cli-output.ts +259 -80
  858. package/src/utils/contract-month.ts +16 -0
  859. package/src/utils/crypto-pair.ts +61 -3
  860. package/src/utils/currency-units.ts +29 -0
  861. package/src/utils/datetime-format.ts +10 -0
  862. package/src/utils/debug-log.ts +1 -1
  863. package/src/utils/decimal-comma.ts +39 -6
  864. package/src/utils/exchange-announcements.ts +71 -0
  865. package/src/utils/exchange-rate-snapshot.ts +10 -0
  866. package/src/utils/financial-statements.ts +83 -4
  867. package/src/utils/format.ts +34 -16
  868. package/src/utils/fundamentals.ts +150 -34
  869. package/src/utils/fx-market-hours.ts +10 -1
  870. package/src/utils/latest-financial-period.ts +8 -0
  871. package/src/utils/linux-libc.ts +54 -0
  872. package/src/utils/market-capitalization.ts +111 -15
  873. package/src/utils/max-drawdown.ts +64 -0
  874. package/src/utils/network-failure.ts +83 -0
  875. package/src/utils/option-expiry.ts +139 -7
  876. package/src/utils/price-earnings.ts +11 -5
  877. package/src/utils/price-history.ts +18 -8
  878. package/src/utils/price-window.ts +131 -0
  879. package/src/utils/release-date.ts +47 -0
  880. package/src/utils/sec.ts +3 -0
  881. package/src/utils/throttled-fetch.ts +11 -4
  882. package/src/utils/trailing-eps.ts +67 -0
  883. package/src/utils/typed-text.ts +21 -0
  884. package/src/utils/utc-time.ts +24 -1
  885. package/src/version.ts +6 -0
  886. package/src/cli/pane-functions/screenshot.ts +0 -2122
@@ -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[] = [{
@@ -16,6 +16,7 @@ import { connectSignedInBrokerProfile } from "../../../brokers/signed-in/connect
16
16
  import {
17
17
  addTickerToPortfolio,
18
18
  adoptFirstPositionCurrency,
19
+ LotCostFxMergeError,
19
20
  createManualPortfolio as createManualPortfolioConfig,
20
21
  deleteManualPortfolio,
21
22
  deleteWatchlist as deleteWatchlistConfig,
@@ -27,6 +28,14 @@ import {
27
28
  validatePositionShares,
28
29
  } from "../../../portfolio/mutations";
29
30
  import { loadFuturesEntrySize } from "../../../portfolio/futures-terms";
31
+ import {
32
+ FORM_COST_FX_WORDING, PositionCostFxError, readCostFxRate, readPurchaseDate, resolvePositionCostFx,
33
+ } from "../../../portfolio/cost-fx";
34
+ import { getManualPortfolioPositionPrefill } from "../../../portfolio/manual-lots";
35
+ import { resolvePortfolioTotalsCurrency } from "../../../portfolio/totals-currency";
36
+ import { createBaseConverter } from "../../../cli/base-converter";
37
+ import { heldCurrencyUnit } from "../../../utils/currency-units";
38
+ import { positionCostTermsPrefill } from "./portfolio-position";
30
39
  import { wholeUnitQuantityProblem } from "../../../portfolio/position-quantity";
31
40
  import type { CommandBarFieldValue } from "./types";
32
41
  import type { WorkflowStringValues } from "./broker";
@@ -126,6 +135,7 @@ export function createCommandBarCollectionWorkflowActions(options: {
126
135
  const connected = await connectSignedInBrokerProfile(broker, {
127
136
  getConfig: () => pluginRegistry.getConfig(),
128
137
  createBrokerInstance: (brokerType, label, values) => pluginRegistry.createBrokerInstance(brokerType, label, values),
138
+ enableBrokerInstance: (instanceId) => pluginRegistry.updateBrokerInstance(instanceId, {}, { enabled: true }),
129
139
  syncBrokerInstance: (instanceId) => pluginRegistry.syncBrokerInstance(instanceId),
130
140
  requestSignIn: requestBrokerSignIn,
131
141
  });
@@ -271,16 +281,45 @@ export function createCommandBarCollectionWorkflowActions(options: {
271
281
  currentState.config.baseCurrency,
272
282
  size?.currency,
273
283
  );
274
- const result = setManualPortfolioPosition(ticker, portfolio.id, {
275
- shares,
276
- avgCost,
277
- currency,
278
- ...(size ? { multiplier: size.multiplier } : {}),
279
- });
284
+ // Purchase Date and Cost FX behave as `position set --date/--cost-fx`. A field left as it opened keeps
285
+ // what the lots have; one emptied clears it; a new date reads that day's FX close unless a rate is typed.
280
286
  const firstPosition = !hasOpenPortfolioPositions(portfolio.id, getState().tickers.values());
287
+ const adopted = firstPosition ? adoptFirstPositionCurrency(getState().config, portfolio.id, currency) : null;
288
+ const valued = adopted ?? getState().config;
289
+ const portfolioCurrency = resolvePortfolioTotalsCurrency(
290
+ valued.portfolios.find((entry) => entry.id === portfolio.id) ?? portfolio, valued.baseCurrency);
291
+ const opened = positionCostTermsPrefill(getManualPortfolioPositionPrefill(ticker, portfolio.id).position, portfolioCurrency);
292
+ const dateText = coerceFieldString(values.dateAcquired).trim();
293
+ const rateText = coerceFieldString(values.costFx).trim();
294
+ const dateAcquired = dateText === opened.dateAcquired ? undefined : dateText ? readPurchaseDate(dateText, FORM_COST_FX_WORDING) : null;
295
+ const typedRate = rateText && rateText !== opened.costFx ? readCostFxRate(rateText, FORM_COST_FX_WORDING) : undefined;
296
+ const toPortfolio = createBaseConverter(dataProvider, heldCurrencyUnit(portfolioCurrency).currency);
297
+ let result: ReturnType<typeof setManualPortfolioPosition>;
298
+ try {
299
+ const bought = await resolvePositionCostFx({
300
+ date: dateAcquired ?? undefined, costFx: typedRate, history: apiClient,
301
+ currency, portfolioCurrency, listing: ticker.metadata.ticker, wording: FORM_COST_FX_WORDING,
302
+ // Today's rate, in the units the lot is held in: what a typed rate is checked against.
303
+ todaysRate: async () => (await toPortfolio(1, heldCurrencyUnit(currency).currency))
304
+ / heldCurrencyUnit(currency).divisor * heldCurrencyUnit(portfolioCurrency).divisor,
305
+ });
306
+ const costFx = bought ? bought.costFx : !rateText && opened.costFx ? null : undefined;
307
+ result = setManualPortfolioPosition(ticker, portfolio.id, {
308
+ shares,
309
+ avgCost,
310
+ currency,
311
+ ...(size ? { multiplier: size.multiplier } : {}),
312
+ ...(dateAcquired !== undefined ? { dateAcquired } : {}),
313
+ ...(costFx !== undefined ? { costFx } : {}),
314
+ });
315
+ } catch (error) {
316
+ // The form shows one message: what is wrong, then what to give instead.
317
+ if (error instanceof PositionCostFxError && error.details) throw new Error(`${error.message} ${error.details}`);
318
+ if (error instanceof LotCostFxMergeError) throw new Error(`${error.message} Give its Cost FX or Purchase Date.`);
319
+ throw error;
320
+ }
281
321
  await tickerRepository.saveTicker(result.ticker);
282
322
  dispatch({ type: "UPDATE_TICKER", ticker: result.ticker });
283
- const adopted = firstPosition ? adoptFirstPositionCurrency(getState().config, portfolio.id, currency) : null;
284
323
  if (adopted) {
285
324
  dispatch({ type: "SET_CONFIG", config: adopted });
286
325
  persistConfig(adopted);
@@ -1,7 +1,7 @@
1
1
  import type { TickerRecord } from "../../../types/ticker";
2
- import { canonicalExchange, parsePublicTickerKey } from "../../../utils/exchanges";
2
+ import { canonicalExchange, parsePublicTickerKey, publicTickerKey } from "../../../utils/exchanges";
3
3
  import { resolveCurrencyUnit } from "../../../utils/currency-units";
4
- import { tickerHasListingSuffix, listingSuffixConflictsWithExchange, listingSuffixExchange } from "../../../sources/listing-symbols";
4
+ import { tickerHasListingSuffix, listingSuffixConflictsWithExchange, listingSuffixExchange, listingSuffixVenue } from "../../../sources/listing-symbols";
5
5
  import { classifyInstrumentKind } from "../../../tickers/search/ranking";
6
6
  import { searchContractKey } from "../../../tickers/search/identity";
7
7
  import type { CollectionKind } from "./tickers";
@@ -42,6 +42,34 @@ function ownsCollection(ticker: TickerRecord, kind: CollectionKind, collectionId
42
42
  || (kind === "portfolio" && ticker.metadata.positions.some((position) => !collectionId || position.portfolio === collectionId));
43
43
  }
44
44
 
45
+ /**
46
+ * The row a research alias under a vendor's suffixed key (GARAN.IS, opened
47
+ * from a link) joins a collection as: its listing's own row, saved under the
48
+ * key GARAN:BIST is saved under, or a new one there. Null for any other row.
49
+ */
50
+ function listingRow(
51
+ ticker: TickerRecord,
52
+ equivalent: readonly TickerRecord[],
53
+ tickers: ReadonlyMap<string, TickerRecord>,
54
+ ): TickerRecord | null {
55
+ if ((ticker.metadata.broker_contracts ?? []).length > 0) return null;
56
+ const parsed = parsePublicTickerKey(ticker.metadata.ticker);
57
+ const venue = listingSuffixVenue(parsed.symbol, parsed.exchange ?? ticker.metadata.exchange);
58
+ if (!venue) return null;
59
+ const own = equivalent.find((candidate) => !tickerHasListingSuffix(parsePublicTickerKey(candidate.metadata.ticker).symbol));
60
+ if (own) return own;
61
+ const onVenue = (row: TickerRecord | undefined) => !!row && canonicalExchange(row.metadata.exchange) === venue.exchange;
62
+ const bare = tickers.get(venue.symbol);
63
+ const venueKey = publicTickerKey(venue.symbol, venue.exchange);
64
+ if (onVenue(bare)) return bare!;
65
+ if (onVenue(tickers.get(venueKey))) return tickers.get(venueKey)!;
66
+ // A new row takes the key adding GARAN:BIST takes: the bare symbol while it is free.
67
+ const key = bare ? venueKey : venue.symbol;
68
+ if (tickers.has(key)) return null;
69
+ const { mergedLots: _lots, ...metadata } = ticker.metadata;
70
+ return { metadata: { ...metadata, ticker: key, exchange: venue.exchange, portfolios: [], watchlists: [], positions: [], tags: [], custom: {} } };
71
+ }
72
+
45
73
  /** Research aliases must not hide or duplicate the saved record that owns a holding. */
46
74
  export function resolveCollectionTicker(
47
75
  ticker: TickerRecord,
@@ -51,7 +79,7 @@ export function resolveCollectionTicker(
51
79
  ): TickerRecord {
52
80
  ticker = tickers.get(ticker.metadata.ticker) ?? ticker;
53
81
  const identity = listingIdentity(ticker);
54
- if (!identity) return ticker;
82
+ if (!identity) return listingRow(ticker, [], tickers) ?? ticker;
55
83
  const equivalent = [...new Map([...tickers, [ticker.metadata.ticker, ticker]]).values()]
56
84
  .filter((candidate) => listingIdentity(candidate) === identity);
57
85
  const owners = equivalent.filter((candidate) => ownsCollection(candidate, kind, collectionId));
@@ -61,5 +89,5 @@ export function resolveCollectionTicker(
61
89
  // If existing records own different collections, the requested empty record
62
90
  // can join a new collection without changing either existing owner.
63
91
  const otherOwners = collectionId ? equivalent.filter((candidate) => ownsCollection(candidate, kind)) : [];
64
- return otherOwners.length === 1 ? otherOwners[0]! : ticker;
92
+ return otherOwners.length === 1 ? otherOwners[0]! : listingRow(ticker, equivalent, tickers) ?? ticker;
65
93
  }
@@ -47,6 +47,12 @@ export function keysClearedByChange(
47
47
  return clearOnChange && !Object.is(previous, next) ? clearOnChange : [];
48
48
  }
49
49
 
50
+ /** A wizard step's condition as the workflow field's list: one answer, or every one of several. */
51
+ function wizardDependencies(dependsOn: WizardStep["dependsOn"]): FieldDependency[] | undefined {
52
+ if (!dependsOn) return undefined;
53
+ return (Array.isArray(dependsOn) ? dependsOn : [dependsOn]).map(({ key, value }) => ({ key, value }));
54
+ }
55
+
50
56
  /** The answer a wizard step starts on: its default, else a select's first option. */
51
57
  function wizardStepInitialValue(step: WizardStep): string | undefined {
52
58
  if (step.defaultValue) return step.defaultValue;
@@ -175,7 +181,7 @@ export function normalizeWizardFields(steps: WizardStep[]): {
175
181
  placeholder: step.placeholder,
176
182
  description: step.body?.[0],
177
183
  required: step.required !== false,
178
- dependsOn: step.dependsOn ? [{ key: step.dependsOn.key, value: step.dependsOn.value }] : undefined,
184
+ dependsOn: wizardDependencies(step.dependsOn),
179
185
  clearOnChange: step.clearOnChange,
180
186
  });
181
187
  continue;
@@ -188,7 +194,7 @@ export function normalizeWizardFields(steps: WizardStep[]): {
188
194
  placeholder: step.placeholder,
189
195
  description: step.body?.[0],
190
196
  required: step.required !== false,
191
- dependsOn: step.dependsOn ? [{ key: step.dependsOn.key, value: step.dependsOn.value }] : undefined,
197
+ dependsOn: wizardDependencies(step.dependsOn),
192
198
  clearOnChange: step.clearOnChange,
193
199
  });
194
200
  }
@@ -1,6 +1,7 @@
1
1
  import { type LayoutConfig, type PaneBinding, type PaneInstanceConfig } from "../../../types/config";
2
2
  import type { PaneSettingField, PaneTemplateContext, PaneTemplateCreateOptions, PaneTemplateInstanceConfig, PaneTemplateDef } from "../../../types/plugin";
3
3
  import { getFocusedCollectionId, getFocusedTickerSymbol } from "../../../state/app/context";
4
+ import { commandPromptTicker } from "../../../layout/selected-ticker";
4
5
  import { resolveInstrumentForPane, resolveListingForPane } from "../../../core/state/app/instrument";
5
6
  import { resolveTickerOpenTarget, tickerOpenFailureMessage } from "../../../tickers/open-target";
6
7
  import { instrumentFromTicker } from "../../../market-data/request-types";
@@ -20,7 +21,7 @@ import {
20
21
  buildRelationshipGraphPaneTitle,
21
22
  } from "../../../plugins/builtin/correlation/relationship/model";
22
23
  import { buildQuoteMonitorPaneTitle } from "../../../plugins/builtin/ticker-detail/settings";
23
- import { getPaneTemplateDisplayLabel } from "../pane-templates/items";
24
+ import { getPaneTemplateDisplayLabel, paneTemplateArgError } from "../pane-templates/items";
24
25
  import { automationActive, describeUsageFunction, recordFunctionOpen } from "../../../telemetry/usage-counts";
25
26
  import { attentionActionForPane, captureAttentionAction } from "../../../telemetry/attention-counts";
26
27
  import { publicTickerKey } from "../../../utils/exchanges";
@@ -101,13 +102,20 @@ async function resolvePaneTemplateOptions(
101
102
  resolvedOptions: PaneTemplateCreateOptions | undefined;
102
103
  }> {
103
104
  const state = deps.getState();
105
+ const focusedSymbol = getFocusedTickerSymbol(state);
106
+ // A required ticker follows the prompt, including a linked desk the focused
107
+ // pane does not hold. An optional ticker stays unbound unless one was named.
108
+ const requiresTicker = (template.shortcut?.argPlaceholder === "ticker" || template.shortcut?.argKind === "ticker")
109
+ && !template.shortcut?.argOptional;
110
+ const prompt = requiresTicker ? commandPromptTicker(state) : null;
111
+ const tickerRootId = prompt?.rootInstanceId ?? state.focusedPaneId;
104
112
  const baseContext: PaneTemplateContext = {
105
113
  config: state.config,
106
114
  layout: state.config.layout,
107
115
  focusedPaneId: state.focusedPaneId,
108
- activeTicker: getFocusedTickerSymbol(state),
109
- activeInstrument: state.focusedPaneId ? resolveInstrumentForPane(state, state.focusedPaneId)?.instrument : undefined,
110
- activeListing: state.focusedPaneId ? resolveListingForPane(state, state.focusedPaneId) : undefined,
116
+ activeTicker: prompt?.symbol ?? focusedSymbol,
117
+ activeInstrument: tickerRootId ? resolveInstrumentForPane(state, tickerRootId)?.instrument : undefined,
118
+ activeListing: tickerRootId ? resolveListingForPane(state, tickerRootId) : undefined,
111
119
  activeCollectionId: getFocusedCollectionId(state),
112
120
  };
113
121
 
@@ -226,6 +234,12 @@ export async function createPaneTemplateOrThrow(
226
234
 
227
235
  const { context, resolvedOptions } = await resolvePaneTemplateOptions(template, options, deps);
228
236
 
237
+ // A name the function knows nothing of opens nothing, rather than its default view.
238
+ const argError = paneTemplateArgError(template, resolvedOptions?.arg, context);
239
+ if (argError) {
240
+ throw new Error(argError.detail ? `${argError.message}. ${argError.detail}.` : `${argError.message}.`);
241
+ }
242
+
229
243
  if (template.canCreate && !template.canCreate(context, resolvedOptions)) {
230
244
  throw new Error(uncoveredTemplateMessage(template, deps.pluginRegistry, resolvedOptions)
231
245
  ?? `Can't create ${getPaneTemplateDisplayLabel(template).toLowerCase()} right now.`);