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
@@ -1,12 +1,14 @@
1
1
  import type { DataProvider } from "../types/data-provider";
2
2
  import type { TickerRecord } from "../types/ticker";
3
- import { listingFields, savedListingName, type ListingChoice } from "./listing-arg";
3
+ import { listingFields, listingVenues, savedListingName, type ListingChoice } from "./listing-arg";
4
4
  import { StagedTickerRepository, type TickerSource } from "./staged-tickers";
5
5
  import { symbolInputKey } from "./symbol-args";
6
- import { describeSuggestion, isPlainNoMatch, suggestListings } from "./listing-suggestion";
6
+ import { describeSuggestion, isPlainNoMatch, suggestListings, suggestUsTicker } from "./listing-suggestion";
7
+ import { NotASymbolError } from "./symbol-cells";
7
8
  import {
8
9
  CoinListingError,
9
10
  ListingChoiceError,
11
+ LookupUnansweredError,
10
12
  resolveCliTicker,
11
13
  resolveTickersForCli,
12
14
  TickerNotFoundError,
@@ -18,16 +20,21 @@ import { isUsSymbolVenue, LOOKUP_TIMEOUT_MS, tickerChangeLine, tickerChangeSymbo
18
20
  import { isVenueAbroad } from "../tickers/listing-fate";
19
21
  import { sameCompany } from "../tickers/company-name";
20
22
  import { tickerHasListingSuffix } from "../sources/listing-symbols";
21
- import { canonicalExchange, resolveExchangeTimeZone } from "../utils/exchanges";
23
+ import { canonicalExchange, exchangeLabel, resolveExchangeTimeZone } from "../utils/exchanges";
22
24
  import { isCurrencyPairListing } from "../utils/fx-market-hours";
25
+ import { isCurrencyCode } from "../utils/currency-pair";
26
+ import { logFailure } from "../utils/log-failure";
23
27
 
24
28
  /**
25
29
  * What became of one symbol of an add or remove. `needs_choice`: a symbol of
26
30
  * an add whose company moved or merged away, whose listing stopped trading, or
27
31
  * that matched only a listing abroad; it is not added, and the row offers what
28
- * to add instead.
32
+ * to add instead. `not_a_symbol`: an entry refused before any lookup (`N/A`,
33
+ * `$$$`, a price). `not_looked_up`: Gloom Cloud kept refusing its lookup, so
34
+ * it is neither found nor missing, and is worth adding again.
29
35
  */
30
- export type SymbolStatus = "added" | "already_listed" | "removed" | "not_listed" | "not_found" | "needs_choice" | "failed";
36
+ export type SymbolStatus =
37
+ | "added" | "already_listed" | "removed" | "not_listed" | "not_found" | "needs_choice" | "failed" | "not_a_symbol" | "not_looked_up";
31
38
 
32
39
  /** One symbol's line: the `--json` and `--csv` row, and a line of text. */
33
40
  export interface SymbolRow extends Record<string, unknown> {
@@ -65,6 +72,8 @@ export interface SymbolRow extends Record<string, unknown> {
65
72
  tradesAs?: string | null;
66
73
  /** An added row's line saying that company moved or merged away, so the listing stored is another's. */
67
74
  changeNote?: string;
75
+ /** A bare symbol added on its only listing, abroad: "GARAN has no US listing; it trades on BIST, in TRY." */
76
+ abroad?: string;
68
77
  }
69
78
 
70
79
  export type Verb = "add" | "remove";
@@ -91,7 +100,15 @@ export function listingRow(
91
100
  ...readAs ? { readAs } : {}, ...extra };
92
101
  }
93
102
 
94
- export function failedRow(input: string, error: Error, status: SymbolStatus = error instanceof TickerNotFoundError ? "not_found" : "failed"): SymbolRow {
103
+ /** The status a failure gives its row: not found, not a symbol, not looked up, or failed for its own reason. */
104
+ function failureStatus(error: Error): SymbolStatus {
105
+ if (error instanceof TickerNotFoundError) return "not_found";
106
+ if (error instanceof NotASymbolError) return "not_a_symbol";
107
+ if (error instanceof LookupUnansweredError) return "not_looked_up";
108
+ return "failed";
109
+ }
110
+
111
+ export function failedRow(input: string, error: Error, status: SymbolStatus = failureStatus(error)): SymbolRow {
95
112
  const hint = error instanceof CoinListingError ? error.hint : null;
96
113
  const choice = error instanceof ListingChoiceError
97
114
  ? { choices: error.choices, listingCount: error.listingCount, ...error.successor ? { successor: error.successor } : {} }
@@ -156,6 +173,77 @@ function isListedAbroad(ticker: TickerRecord): boolean {
156
173
  return !isUsSymbolVenue(venue) && !!currency && currency !== "USD";
157
174
  }
158
175
 
176
+ /** A bare US-shaped symbol (JPM, BRK.B), not 7203 or RY.TO, which name a venue of their own. */
177
+ function bareUsShapedSymbol(resolution: Pick<CliTicker, "bareSymbol">): string | null {
178
+ const symbol = resolution.bareSymbol;
179
+ return symbol && tickerChangeSymbol(symbol) && !tickerHasListingSuffix(symbol) ? symbol : null;
180
+ }
181
+
182
+ type SymbolDeps = { store: TickerSource; dataProvider: DataProvider };
183
+
184
+ const NO_SAVED_ROWS = { loadTicker: async () => null, loadAllTickers: async () => [] };
185
+
186
+ /**
187
+ * Whether a bare symbol also names a US listing: a US company had or has it
188
+ * (its change history: DFS was Discover Financial Services), or it lists on
189
+ * a US venue, by the venues the lookup saw or, when it asked none (a saved
190
+ * row, read with no search), by search now, else by the symbol's own quote,
191
+ * which names its US line first. When neither answers it counts as naming
192
+ * one, so the match stays a choice.
193
+ */
194
+ async function namesUsListing(resolution: CliTicker, deps: SymbolDeps): Promise<boolean> {
195
+ if (resolution.change || resolution.formerIssuer) return true;
196
+ if (resolution.otherVenues) return resolution.otherVenues.some((venue) => isUsSymbolVenue(venue));
197
+ const symbol = resolution.bareSymbol!;
198
+ // Search's listings, not the saved row it would answer with; none found (or search failed) says nothing.
199
+ const venues = await listingVenues(symbol, { store: NO_SAVED_ROWS, dataProvider: deps.dataProvider })
200
+ .catch(logFailure("cli.symbol-rows", "Read listing venues failed", []));
201
+ if (venues.length > 0) return venues.some((venue) => isUsSymbolVenue(venue.exchange));
202
+ const quote = await deps.dataProvider.getQuote(symbol, "").catch(logFailure("cli.symbol-rows", "Quote bare symbol failed", null));
203
+ const venue = canonicalExchange(quote?.listingExchangeName || quote?.exchangeName);
204
+ return !venue || isUsSymbolVenue(venue);
205
+ }
206
+
207
+ /**
208
+ * Whether a bare symbol is stored on its listing abroad, still trading, and
209
+ * that is all it names (`namesUsListing`): GARAN is added on BIST, saying so.
210
+ */
211
+ async function listedOnlyAbroad(resolution: CliTicker, deps: SymbolDeps): Promise<boolean> {
212
+ if (!bareUsShapedSymbol(resolution) || resolution.ended || !isListedAbroad(resolution.ticker)) return false;
213
+ return !await namesUsListing(resolution, deps);
214
+ }
215
+
216
+ /** "GARAN has no US listing; it trades on BIST, in TRY.": the line an add says beside a symbol `listedOnlyAbroad`. */
217
+ function abroadOnlyNote(resolution: CliTicker): string {
218
+ const { exchange, currency } = resolution.ticker.metadata;
219
+ const unit = currency?.trim();
220
+ return `${resolution.bareSymbol} has no US listing; it trades on ${exchangeLabel(exchange)}${unit ? `, in ${unit}` : ""}.`;
221
+ }
222
+
223
+ /**
224
+ * What a bare symbol listed only abroad was more likely typed for: a
225
+ * currency (MXN, mixi Inc in Stuttgart) or a US ticker one slip away (APPL,
226
+ * Aptus Pharma in Mumbai, for AAPL). "APPL is one slip from AAPL (Apple
227
+ * Inc.)" or "MXN is also a currency"; null when the symbol is likely meant as typed.
228
+ */
229
+ async function meantInstead(symbol: string, deps: SymbolDeps): Promise<string | null> {
230
+ if (symbol !== "USD" && /^[A-Z]{3}$/.test(symbol) && isCurrencyCode(symbol)) return `${symbol} is also a currency`;
231
+ const suggestion = await suggestUsTicker(symbol, deps).catch(logFailure("cli.symbol-rows", "Suggest a US ticker failed", null));
232
+ return suggestion ? `${symbol} is one slip from ${describeSuggestion(suggestion)}` : null;
233
+ }
234
+
235
+ /**
236
+ * How a bare symbol matched abroad is settled: `abroad` when it is added
237
+ * there, with its line, or `meant` when it is left for a choice as more
238
+ * likely typed for something else. Both null for anything else, which
239
+ * `choiceNeeded` decides.
240
+ */
241
+ async function settleAbroad(resolution: CliTicker, deps: SymbolDeps): Promise<{ abroad: string | null; meant: string | null; onlyAbroad: boolean }> {
242
+ if (!await listedOnlyAbroad(resolution, deps)) return { abroad: null, meant: null, onlyAbroad: false };
243
+ const meant = await meantInstead(resolution.bareSymbol!, deps);
244
+ return { abroad: meant ? null : abroadOnlyNote(resolution), meant, onlyAbroad: true };
245
+ }
246
+
159
247
  /** Whether a YYYY-MM-DD day is within `ms` before `now`. */
160
248
  function within(day: string | null, ms: number, now: number): boolean {
161
249
  const at = day ? Date.parse(day.slice(0, 10)) : Number.NaN;
@@ -164,27 +252,34 @@ function within(day: string | null, ms: number, now: number): boolean {
164
252
 
165
253
  /**
166
254
  * Why a symbol of an add that named no exchange is not stored as it matched:
167
- * the listing found stopped trading (NYCB:NYSE), it is a listing abroad (DFS
168
- * Furniture's DFS:LSE for DFS), or the company that had the symbol left it in
255
+ * the listing found stopped trading (NYCB:NYSE), it is a listing abroad while
256
+ * the symbol also names a US one (DFS Furniture's DFS:LSE for DFS, Discover's
257
+ * old symbol) or was likely typed for something else (`meantInstead`: APPL
258
+ * for AAPL), or the company that had the symbol left it in
169
259
  * the last two years (BRKL, Brookline Bancorp's until 2025, now a fund's). The message
170
260
  * leads with what became of the company that held the symbol, when the
171
261
  * symbol's history says ("DFS was Discover Financial Services until 2025, now
172
262
  * Capital One Financial: COF"), whose symbol now is the successor offered; the
173
263
  * match is offered too. Null for a match stored as it is: a trading US
174
264
  * listing whose symbol changed hands longer ago (its row says so) or never,
175
- * or one whose input named its exchange; coins, perpetual markets and
176
- * currency pairs, which trade in no one country, too.
265
+ * a listing abroad that is all the symbol names (GARAN:BIST for GARAN, said
266
+ * with `abroadOnlyNote`), or one whose input named its exchange; coins,
267
+ * perpetual markets and currency pairs, which trade in no one country, too.
177
268
  */
178
- function choiceNeeded(resolution: CliTicker, now = Date.now()): { message: string; successor: string | null } | null {
179
- const symbol = resolution.bareSymbol;
180
- // A US-shaped symbol (JPM, BRK.B), not 7203 or RY.TO, which name a venue of their own.
181
- if (!symbol || !tickerChangeSymbol(symbol) || tickerHasListingSuffix(symbol)) return null;
269
+ function choiceNeeded(
270
+ resolution: CliTicker,
271
+ { onlyAbroad, meant }: { onlyAbroad: boolean; meant: string | null },
272
+ now = Date.now(),
273
+ ): { message: string; successor: string | null } | null {
274
+ const symbol = bareUsShapedSymbol(resolution);
275
+ if (!symbol) return null;
182
276
  const history = successorOf(resolution);
183
277
  const label = savedListingName(resolution.ticker).label;
184
278
  // A company that left lately: the match is another's, or that company's own line, still quoted.
185
279
  const recent = !!history?.successor && within(history.left, RECENT_REUSE_MS, now);
186
280
  const found = resolution.ended
187
- ?? (isListedAbroad(resolution.ticker) ? `${symbol} matched ${label}, a listing abroad`
281
+ ?? (isListedAbroad(resolution.ticker) && (!onlyAbroad || meant)
282
+ ? `${symbol} matched ${label}, a listing abroad${meant ? `; ${meant}` : ""}`
188
283
  : recent ? `${symbol} matched ${label}, ${sameCompany(resolution.ticker.metadata.name, history?.company) ? "that company's old line" : "another company's listing"}`
189
284
  : null);
190
285
  if (!found) return null;
@@ -201,7 +296,9 @@ export const NO_MATCH = /^No ticker match found for /;
201
296
  * went nowhere are named so the list can be fixed.
202
297
  */
203
298
  export function summarizeSymbolRows(rows: readonly SymbolRow[], verb: Verb, repeated: number): string {
204
- const inputs = (status: SymbolStatus) => rows.filter((row) => row.status === status).map((row) => symbolInputKey(row.input));
299
+ // An entry that is no symbol, or was not looked up, is named as it was written: `$$$`, `philip morris intl`.
300
+ const inputs = (status: SymbolStatus) => rows.filter((row) => row.status === status)
301
+ .map((row) => status === "not_a_symbol" || status === "not_looked_up" ? row.input.trim() : symbolInputKey(row.input));
205
302
  const counts = SETTLED[verb]
206
303
  .map(([status, word], index) => ({ count: inputs(status).length, word, index }))
207
304
  .filter(({ count, index }) => index === 0 || count > 0)
@@ -213,6 +310,12 @@ export function summarizeSymbolRows(rows: readonly SymbolRow[], verb: Verb, repe
213
310
  if (choices.length > 0) groups.push(`${choices.length} need${choices.length === 1 ? "s" : ""} a choice: ${choices.join(", ")}`);
214
311
  const failed = inputs("failed");
215
312
  if (failed.length > 0) groups.push(`${failed.length} not ${verb === "add" ? "added" : "removed"}: ${failed.join(", ")}`);
313
+ const unanswered = inputs("not_looked_up");
314
+ if (unanswered.length > 0) groups.push(`${unanswered.length} not looked up: ${unanswered.join(", ")}`);
315
+ const junk = inputs("not_a_symbol");
316
+ if (junk.length > 0) {
317
+ groups.push(`${junk.length} not ${junk.length === 1 ? "a symbol" : "symbols"}: ${junk.join(junk.some((input) => input.includes(",")) ? "; " : ", ")}`);
318
+ }
216
319
  if (repeated > 0) groups.push(`${repeated} repeat${repeated === 1 ? "" : "s"} skipped`);
217
320
  return `${groups.join("; ")}.`;
218
321
  }
@@ -248,6 +351,7 @@ async function settleAdd(
248
351
  input: string,
249
352
  lookup: CliTickerResolution,
250
353
  staged: StagedTickerRepository,
354
+ dataProvider: DataProvider,
251
355
  add: AddTicker,
252
356
  added: Set<string>,
253
357
  ): Promise<AddOutcome> {
@@ -258,7 +362,8 @@ async function settleAdd(
258
362
  ? { row: { ...failedRow(input, error, "needs_choice"), tradesAs: error.successor }, error }
259
363
  : { row: failedRow(input, error), error };
260
364
  }
261
- const choice = choiceNeeded(lookup);
365
+ const abroad = await settleAbroad(lookup, { store: staged, dataProvider });
366
+ const choice = choiceNeeded(lookup, abroad);
262
367
  if (choice) {
263
368
  // The lookup saved the listing it matched; one that is in no list of this run is not kept.
264
369
  if (!added.has(lookup.ticker.metadata.ticker)) staged.discard(lookup.ticker.metadata.ticker);
@@ -281,7 +386,7 @@ async function settleAdd(
281
386
  const history = successorOf(lookup);
282
387
  return { row: listingRow(input, result.changed ? "added" : "already_listed", result.ticker, {
283
388
  notes: lookup.notes, ended: lookup.ended, hint: lookup.coinNote, readAs: lookup.readAs,
284
- extra: history ? { changeNote: history.note, tradesAs: history.successor } : {},
389
+ extra: { ...history ? { changeNote: history.note, tradesAs: history.successor } : {}, ...abroad.abroad ? { abroad: abroad.abroad } : {} },
285
390
  }), error: null };
286
391
  }
287
392
 
@@ -337,7 +442,7 @@ export async function addSymbols({
337
442
  rows.push(failedRow(input, refusal ?? new Error("Not looked up.")));
338
443
  continue;
339
444
  }
340
- const { row } = await settleAdd(input, resolution, staged, add, added);
445
+ const { row } = await settleAdd(input, resolution, staged, dataProvider, add, added);
341
446
  rows.push(resolution.error && row.status !== "needs_choice" && failure ? failedRow(input, failure(resolution.error)) : row);
342
447
  }
343
448
  if (!dryRun) await staged.commit();
@@ -374,15 +479,16 @@ export async function addSymbol(
374
479
  } catch (caught) {
375
480
  lookup = { input, error: caught instanceof Error ? caught : new Error(String(caught)) };
376
481
  }
377
- const outcome = await settleAdd(input, lookup, staged, add, new Set());
482
+ const outcome = await settleAdd(input, lookup, staged, dataProvider, add, new Set());
378
483
  if (!dryRun) await staged.commit();
379
484
  return { ...outcome, lookup: lookup.error ? null : lookup };
380
485
  }
381
486
 
382
487
  /**
383
- * Why a typed symbol the command bar adds on its own would not be stored as
384
- * it matched (`settleAdd`), as a pasted list would leave it: its needs-choice
385
- * row, else null, for the single add to go on as it does. Nothing is saved.
488
+ * How a typed symbol the command bar adds on its own is decided, as a symbol
489
+ * of a pasted list is (`settleAdd`): a needs-choice row when it would not be
490
+ * stored as it matched, else the row it would add, which says when it is
491
+ * listed only abroad; null when nothing was looked up. Nothing is saved.
386
492
  */
387
493
  export async function typedSymbolChoice(input: string, store: TickerSource, dataProvider: DataProvider): Promise<SymbolRow | null> {
388
494
  const symbol = input.trim().toUpperCase();
@@ -395,8 +501,8 @@ export async function typedSymbolChoice(input: string, store: TickerSource, data
395
501
  } catch (caught) {
396
502
  lookup = { input: symbol, error: caught instanceof Error ? caught : new Error(String(caught)) };
397
503
  }
398
- const { row } = await settleAdd(symbol, lookup, staged, (ticker) => ({ changed: false, ticker }), new Set());
399
- return row.status === "needs_choice" ? row : null;
504
+ const { row } = await settleAdd(symbol, lookup, staged, dataProvider, (ticker) => ({ changed: false, ticker }), new Set());
505
+ return row;
400
506
  }
401
507
 
402
508
  /** The rows, each symbol search found no listing for with the nearest listing it did find, when that is a near match. */
@@ -1,6 +1,7 @@
1
1
  import { logFailure } from "../utils/log-failure";
2
2
  import type { DataProvider } from "../types/data-provider";
3
3
  import type { Quote } from "../types/financials";
4
+ import type { InstrumentSearchResult } from "../types/instrument";
4
5
  import type { TickerRecord } from "../types/ticker";
5
6
  import type { AppTickerRepositoryPort } from "../core/app-service-ports";
6
7
  import { connectionHealth, GLOOM_CLOUD_HTTP_CONNECTION_ID } from "../core/connection-health";
@@ -15,6 +16,7 @@ import {
15
16
  import { canonicalExchange, parsePublicTickerKey } from "../utils/exchanges";
16
17
  import {
17
18
  chosenListingNote,
19
+ isNoProviderError,
18
20
  ListingArgError,
19
21
  listingChoiceNote,
20
22
  listingReadNotes,
@@ -25,6 +27,7 @@ import {
25
27
  quoteBareListing,
26
28
  resolveCliListing,
27
29
  savedListingName,
30
+ UNLISTED_TYPES,
28
31
  type CliListing,
29
32
  type ListingChoice,
30
33
  type ListingDeps,
@@ -33,6 +36,7 @@ import { listingChangeLine, loadListingFate, noLongerTradingNote, tradingListing
33
36
  import {
34
37
  describeFormerIssuer,
35
38
  describeTickerChange,
39
+ isUsSymbolVenue,
36
40
  movedAwayChange,
37
41
  LOOKUP_TIMEOUT_MS,
38
42
  startTickerChangeLookup,
@@ -46,6 +50,9 @@ import {
46
50
  import { batchedListLookups, type ListLookupPlan } from "../tickers/batched-lookups";
47
51
  import { providerSearchQueries } from "../tickers/search";
48
52
  import { coinElsewhereNote, savedListingCoinNote } from "./commands/crypto-hints";
53
+ import { NotASymbolError, notASymbolError } from "./symbol-cells";
54
+ import { kindFromListingSyntax } from "../tickers/instrument-kind";
55
+ import { normalizeTickerSymbol } from "../tickers/search/ranking";
49
56
 
50
57
  /** The saved ticker for a symbol (`SAN:EPA`, or `SAN` with `--exchange EPA`), saving it from search first if needed. */
51
58
  export async function resolveTickerForCli(
@@ -87,10 +94,18 @@ export interface CliTicker {
87
94
  * the input named its listing, or a company's name was read as one.
88
95
  */
89
96
  bareSymbol: string | null;
97
+ /**
98
+ * The venues other than the stored one the symbol lists on, as far as the
99
+ * lookup saw them: search's, or none when the symbol's own quote named the
100
+ * listing and search was busy. Null when the lookup asked neither (a saved
101
+ * row), so whether a bare symbol matched abroad also names a US listing is
102
+ * still to be asked.
103
+ */
104
+ otherVenues: string[] | null;
90
105
  }
91
106
 
92
107
  export interface CliTickerOptions {
93
- /** The command that takes one listing, for the choices a failure names: `gloomberb watchlist add Growth 2222:JPX`. */
108
+ /** The command that takes one listing, for the choices a failure names: `gloom watchlist add Growth 2222:JPX`. */
94
109
  retry?: (key: string) => string;
95
110
  /** `--exchange` only fills in the symbols that name no exchange of their own, as for a list of symbols. */
96
111
  ownExchangeWins?: boolean;
@@ -159,6 +174,17 @@ export class TickerNotFoundError extends ListingArgError {
159
174
  }
160
175
  }
161
176
 
177
+ /**
178
+ * A list's symbol Gloom Cloud kept refusing to look up, through every wait:
179
+ * the lookup did not happen, so the symbol is neither found nor missing.
180
+ */
181
+ export class LookupUnansweredError extends Error {
182
+ constructor(readonly input: string) {
183
+ super(`Could not look up ${input}: Gloom Cloud did not answer. Try again in a minute.`);
184
+ this.name = "LookupUnansweredError";
185
+ }
186
+ }
187
+
162
188
  /**
163
189
  * `resolveTickerForCli`, saying which listing a bare symbol went to. A bare
164
190
  * symbol goes where `quote` reads it: the listing its own quote is on, else,
@@ -166,7 +192,9 @@ export class TickerNotFoundError extends ListingArgError {
166
192
  * (`quoteBareListing`); a code several companies list asks which. A symbol
167
193
  * search no longer lists, whose quote stopped long ago, is no longer trading,
168
194
  * and a named exchange the symbol is not on says where it is. Those failures
169
- * are `ListingArgError`s, with any choices in `details`.
195
+ * are `ListingArgError`s, with any choices in `details`. What cannot be a
196
+ * symbol (`N/A`, `$$$`, a price such as `2.582,52`) fails with
197
+ * `NotASymbolError` before anything is asked.
170
198
  */
171
199
  export async function resolveCliTicker(
172
200
  symbol: string,
@@ -178,8 +206,11 @@ export async function resolveCliTicker(
178
206
  if (!symbol.trim()) {
179
207
  throw new Error("Ticker symbol is required.");
180
208
  }
209
+ const notSymbol = notASymbolError(symbol);
210
+ if (notSymbol) throw notSymbol;
181
211
  const deps: ListingDeps = { store, dataProvider };
182
- const listing = await resolveCliListing(symbol, exchange, deps, { ownExchangeWins: options.ownExchangeWins });
212
+ // A vendor's suffix is the venue it names (GARAN.IS is GARAN:BIST), so the listing is saved under one key.
213
+ const listing = await resolveCliListing(symbol, exchange, deps, { ownExchangeWins: options.ownExchangeWins, listingSuffix: true });
183
214
  const read = listingReadNotes(listing);
184
215
  // Looked up beside the search, so saying FB is now META costs no wait.
185
216
  const changes = options.changes === false ? null : startTickerChangeLookup(dataProvider, listing.symbol, listing.exchange);
@@ -195,6 +226,20 @@ export async function resolveCliTicker(
195
226
  const saved = options.refreshName === false ? { ticker: listing.saved, quote: null } : await nameFromListingQuote(listing.saved, store, dataProvider, null);
196
227
  return withChange(withEnded(saved, read), { name: saved.ticker.metadata.name });
197
228
  }
229
+ // A listing its own quote names is found as `quote` finds it, the quote cache first, so a busy search never
230
+ // blocks a listing the quote knows. Search is asked after, for the venues a note names, and may fail.
231
+ const known = await listingOfOwnQuote(listing, dataProvider);
232
+ if (known) {
233
+ const { ticker, created } = await upsertTickerFromSearchResult(store, known.result);
234
+ const named = created ? await nameFromListingQuote(ticker, store, dataProvider, known.quote) : { ticker, quote: known.quote };
235
+ const saved = savedListingName(named.ticker);
236
+ const venues = listing.exchange ? [] : await listingVenues(listing.symbol, deps).catch(logFailure("cli.ticker-resolution", "Read quoted listing venues failed", []));
237
+ const others = venues.map((venue) => venue.exchange).filter((venue) => venue !== saved.exchange);
238
+ const venueNote = others.length > 0 && saved.exchange
239
+ ? listingChoiceNote(listing.symbol, saved, venues) ?? chosenListingNote(listing.symbol, saved.exchange, others)
240
+ : null;
241
+ return withChange({ ticker: named.ticker, notes: [...read, ...venueNote ? [venueNote] : []], ended: null, otherVenues: others }, tradingListing(known.quote));
242
+ }
198
243
 
199
244
  const localTickers = new Map(
200
245
  (await store.loadAllTickers()).map((ticker) => [ticker.metadata.ticker.toUpperCase(), ticker] as const),
@@ -203,6 +248,7 @@ export async function resolveCliTicker(
203
248
  let resolved: ResolvedTickerSearch | null;
204
249
  let bareNote: string | null = null;
205
250
  let bareQuote: Quote | null = null;
251
+ let bareVenues: string[] = [];
206
252
  try {
207
253
  resolved = await search(listing.key);
208
254
  } catch (error) {
@@ -224,6 +270,7 @@ export async function resolveCliTicker(
224
270
  resolved = await search(bare.listing.key);
225
271
  bareNote = bare.note;
226
272
  bareQuote = bare.quote;
273
+ bareVenues = error.listings.flatMap((key) => parsePublicTickerKey(key).exchange ?? []).filter((venue) => venue !== bare.listing.exchange);
227
274
  }
228
275
 
229
276
  if (!resolved) {
@@ -238,7 +285,7 @@ export async function resolveCliTicker(
238
285
  }
239
286
  if (resolved.kind === "local") {
240
287
  const local = options.refreshName === false ? { ticker: resolved.ticker, quote: null } : await nameFromListingQuote(resolved.ticker, store, dataProvider, bareQuote);
241
- return withChange(withEnded(local, [...read, ...bareNote ? [bareNote] : []]), { name: local.ticker.metadata.name });
288
+ return withChange({ ...withEnded(local, [...read, ...bareNote ? [bareNote] : []]), otherVenues: bareNote ? bareVenues : null }, { name: local.ticker.metadata.name });
242
289
  }
243
290
 
244
291
  const { ticker, created } = await upsertTickerFromSearchResult(store, resolved.result);
@@ -257,10 +304,50 @@ export async function resolveCliTicker(
257
304
  ticker: named.ticker,
258
305
  notes: [...read, venueNote, ended].filter((note): note is string => !!note),
259
306
  ended,
307
+ otherVenues: bareNote ? bareVenues : others,
260
308
  }, current);
261
309
  }
262
310
 
263
- type ResolvedListing = Omit<CliTicker, "change" | "formerIssuer" | "coinNote" | "readAs" | "bareSymbol">;
311
+ /**
312
+ * The listing a symbol's own quote names, asked as `quote` asks it (the quote
313
+ * cache first): a priced quote answering for that symbol, on the venue named
314
+ * when one was, that still trades. Null when there is none, and for a pair, a
315
+ * future, an index or a coin, which search types; search then looks it up. So
316
+ * is a named US venue: the US exchanges share one symbol, and a quote asked
317
+ * for on any of them answers as that venue (AAPL:NYSE), where search says
318
+ * AAPL trades on NASDAQ.
319
+ */
320
+ async function listingOfOwnQuote(listing: CliListing, dataProvider: DataProvider): Promise<{ result: InstrumentSearchResult; quote: Quote } | null> {
321
+ if (listing.sharedCode || kindFromListingSyntax(listing.key, listing.exchange) || (listing.exchange && isUsSymbolVenue(listing.exchange))) return null;
322
+ let quote: Quote;
323
+ try {
324
+ quote = await dataProvider.getQuote(listing.request.symbol, listing.request.exchange);
325
+ } catch (error) {
326
+ // Search then says what is wrong with the symbol.
327
+ if (!isNoProviderError(error)) logFailure("cli.ticker-resolution", "Quote listing before search failed")(error);
328
+ return null;
329
+ }
330
+ const exchange = canonicalExchange(quote.listingExchangeName || quote.exchangeName);
331
+ const answered = normalizeTickerSymbol(quote.symbol ?? "");
332
+ if (!exchange || (answered !== listing.symbol && answered !== listing.key)) return null;
333
+ if (listing.exchange && exchange !== listing.exchange) return null;
334
+ if (!Number.isFinite(quote.price) || quote.price === 0 || !(quote.lastUpdated > 0)) return null;
335
+ if (quote.delisting || noLongerTradingNote(listing.key, quote)) return null;
336
+ if (UNLISTED_TYPES.has(quote.instrumentType?.trim().toUpperCase() ?? "")) return null;
337
+ return {
338
+ quote,
339
+ result: {
340
+ providerId: dataProvider.id,
341
+ symbol: listing.symbol,
342
+ name: quote.name?.trim() || listing.symbol,
343
+ exchange,
344
+ ...quote.currency ? { currency: quote.currency } : {},
345
+ type: quote.instrumentType || "",
346
+ },
347
+ };
348
+ }
349
+
350
+ type ResolvedListing = Omit<CliTicker, "change" | "formerIssuer" | "coinNote" | "readAs" | "bareSymbol" | "otherVenues"> & { otherVenues?: string[] | null };
264
351
 
265
352
  /**
266
353
  * The resolution with the symbol's change, when it has one, and the coin note
@@ -282,7 +369,7 @@ async function describeResolution(
282
369
  const line = tickerChangeLine(change) ?? formerIssuer?.note;
283
370
  const coinNote = listing.exchange ? null : savedListingCoinNote(listing.symbol, resolved.ticker);
284
371
  return { ...resolved, notes: [...line ? [line] : [], ...resolved.notes, ...coinNote ? [coinNote] : []], change, formerIssuer, coinNote,
285
- readAs: listing.readAs ?? null, bareSymbol: listing.exchange ? null : listing.symbol };
372
+ readAs: listing.readAs ?? null, bareSymbol: listing.exchange ? null : listing.symbol, otherVenues: resolved.otherVenues ?? null };
286
373
  }
287
374
 
288
375
  /**
@@ -368,6 +455,11 @@ function watchFailedRequests(): { count: () => number; stop: () => void } {
368
455
  return { count: () => failures.size, stop: () => { unsubscribe(); dispose?.(); } };
369
456
  }
370
457
 
458
+ /** Whether a lookup's failure may be the service refusing it, so a new look could answer: not one refused before any request. */
459
+ function mayBeRefusal(error: Error): boolean {
460
+ return !(error instanceof NotASymbolError);
461
+ }
462
+
371
463
  function lookUpTickers(
372
464
  symbols: readonly string[],
373
465
  concurrency: number,
@@ -389,8 +481,11 @@ function lookUpTickers(
389
481
  * is searched as it always is.
390
482
  */
391
483
  function listLookupPlan(input: string, exchange: string | undefined): ListLookupPlan {
484
+ // What cannot be a symbol is refused without a request.
485
+ if (notASymbolError(input)) return { searches: [], changes: null };
392
486
  try {
393
- const listing = parseListingArg(input, exchange, { ownExchangeWins: true });
487
+ // GARAN.IS names its venue, as GARAN:BIST does: it is looked up as a named listing is.
488
+ const listing = parseListingArg(input, exchange, { ownExchangeWins: true, listingSuffix: true });
394
489
  const searchable = !listing.exchange && /^[A-Z0-9][A-Z0-9.-]{0,11}$/.test(listing.symbol);
395
490
  return {
396
491
  searches: searchable ? providerSearchQueries(listing.symbol) : [],
@@ -410,7 +505,9 @@ function listLookupPlan(input: string, exchange: string | undefined): ListLookup
410
505
  * few batched requests first (`batchedListLookups`). "Not found" means search
411
506
  * found no listing: while the service refuses requests, the symbols that
412
507
  * failed are looked up again after a pause, and any it still did not answer
413
- * for say so.
508
+ * for fail with `LookupUnansweredError`. One that cannot be a symbol fails
509
+ * with `NotASymbolError` at once: it is never asked for, looked up again or
510
+ * waited for.
414
511
  */
415
512
  export async function resolveTickersForCli(
416
513
  symbols: readonly string[],
@@ -448,7 +545,7 @@ export async function resolveTickersForCli(
448
545
  let lookups = symbols.map((input) => looked.get(input)!);
449
546
  let failing = failedRequests.count() > 0;
450
547
  for (const waitMs of retryWaitsMs) {
451
- const failed = lookups.filter((entry) => entry.error).map((entry) => entry.input);
548
+ const failed = lookups.filter((entry) => entry.error && mayBeRefusal(entry.error)).map((entry) => entry.input);
452
549
  if (!failing || failed.length === 0) break;
453
550
  onRetry?.(failed.length, waitMs);
454
551
  await new Promise((resolveWait) => setTimeout(resolveWait, waitMs));
@@ -459,8 +556,8 @@ export async function resolveTickersForCli(
459
556
  }
460
557
  if (!failing) return lookups;
461
558
  // Still refused after the last wait: a failure may only be the refusal, so none is called not found.
462
- return lookups.map((entry) => entry.error
463
- ? { input: entry.input, error: new Error(`Could not look up ${entry.input}: Gloom Cloud did not answer. Try again in a minute.`) }
559
+ return lookups.map((entry) => entry.error && mayBeRefusal(entry.error)
560
+ ? { input: entry.input, error: new LookupUnansweredError(entry.input) }
464
561
  : entry);
465
562
  } finally {
466
563
  failedRequests.stop();
@@ -68,18 +68,18 @@ export function treasuryYieldTenor(text: string): TreasuryYieldTenor | null {
68
68
  /** The commands with the yield: its Cboe index when there is one, its FRED series, the curve. */
69
69
  function yieldCommands(tenor: TreasuryYieldTenor): Array<readonly [command: string, gives: string]> {
70
70
  return [
71
- ...tenor.index ? [[`gloomberb quote ${tenor.index}`, "Cboe index"] as const] : [],
72
- [`gloomberb fred ${tenor.fred}`, "daily"],
73
- ["gloomberb yield-curve", "every tenor"],
71
+ ...tenor.index ? [[`gloom quote ${tenor.index}`, "Cboe index"] as const] : [],
72
+ [`gloom fred ${tenor.fred}`, "daily"],
73
+ ["gloom yield-curve", "every tenor"],
74
74
  ];
75
75
  }
76
76
 
77
- /** "US 10-year Treasury yield: gloomberb quote ^TNX (Cboe index), ...", for `search`, `catalog` and a bare root. */
77
+ /** "US 10-year Treasury yield: gloom quote ^TNX (Cboe index), ...", for `search`, `catalog` and a bare root. */
78
78
  export function treasuryYieldLine(tenor: TreasuryYieldTenor): string {
79
79
  return `US ${tenor.label} Treasury yield: ${yieldCommands(tenor).map(([command, gives]) => `${command} (${gives})`).join(", ")}.`;
80
80
  }
81
81
 
82
- /** "Try `gloomberb quote ^TNX`, ... for the US 10-year Treasury yield.", after "Not a ticker: US10Y." */
82
+ /** "Try `gloom quote ^TNX`, ... for the US 10-year Treasury yield.", after "Not a ticker: US10Y." */
83
83
  export function treasuryYieldHint(tenor: TreasuryYieldTenor): string {
84
84
  const commands = yieldCommands(tenor).map(([command]) => `\`${command}\``);
85
85
  return `Try ${commands.slice(0, -1).join(", ")} or ${commands.at(-1)} for the US ${tenor.label} Treasury yield.`;
package/src/cli/types.ts CHANGED
@@ -19,6 +19,8 @@ export type MarketContext = ConfigContext & {
19
19
  resolveBroker?: (brokerType: string) => import("../types/broker").BrokerAdapter | null;
20
20
  /** Charts catalog series in a report run without the plugin runtime. */
21
21
  seriesCapabilities?: CapabilityInvoker;
22
+ /** The catalog series charted as an expression (`FRED:DFII10`), in a report run without the plugin runtime. */
23
+ findCatalogSeries?: (expression: string) => import("../series/types").SeriesDefinition | undefined;
22
24
  /** `--refresh`: prefetched data bypasses the local cache. */
23
25
  refresh?: boolean;
24
26
  /** Filings behind the statements and a bank's figures, read from Gloom Cloud; absent where the data service is a stand-in. */
@@ -14,7 +14,7 @@ const VIX_FUNCTION_INDICES: ReadonlySet<string> = new Set(VOLATILITY_INDICES.map
14
14
  export function uncoveredInstrumentCommand(instrument: InstrumentOfKind): string {
15
15
  const symbol = instrument.symbol;
16
16
  const bare = parsePublicTickerKey(symbol).symbol.toUpperCase();
17
- if (instrument.kind === "index" && VIX_FUNCTION_INDICES.has(bare)) return "gloomberb fn VIX";
18
- if (instrument.kind === "fund") return `gloomberb fundamentals ${symbol}`;
19
- return `gloomberb ticker ${symbol}`;
17
+ if (instrument.kind === "index" && VIX_FUNCTION_INDICES.has(bare)) return "gloom fn VIX";
18
+ if (instrument.kind === "fund") return `gloom fundamentals ${symbol}`;
19
+ return `gloom ticker ${symbol}`;
20
20
  }
@@ -22,13 +22,13 @@ function shellWord(arg: string): string {
22
22
 
23
23
  /**
24
24
  * The command that runs `hit` with what the reader typed after the unknown
25
- * word: their tickers (`gloomberb fn RV DUOL --peers`, the switch added when
25
+ * word: their tickers (`gloom fn RV DUOL --peers`, the switch added when
26
26
  * one symbol meets a function that picks its peers), or the function's
27
27
  * placeholder and a search when they typed a company's name.
28
28
  */
29
29
  function catalogHitCommand(hit: CatalogCommandHit, args: readonly string[]): { command: string; search: string | null } {
30
30
  const typed = args.filter((arg) => arg.trim() && !arg.startsWith("-"));
31
- const base = `gloomberb fn ${hit.code}`;
31
+ const base = `gloom fn ${hit.code}`;
32
32
  if (hit.argKind === "none") return { command: base, search: null };
33
33
  const placeholder = hit.argPlaceholder ?? hit.argKind;
34
34
  if (!hit.argKind || !TICKER_ARGUMENTS.has(hit.argKind)) {
@@ -39,7 +39,7 @@ function catalogHitCommand(hit: CatalogCommandHit, args: readonly string[]): { c
39
39
  const single = typed.length === 1;
40
40
  const peers = hit.peers && single ? " --peers" : "";
41
41
  if (names.length > 0) {
42
- return { command: `${base} <${single ? "ticker" : placeholder ?? "tickers"}>${peers}`, search: `gloomberb search ${names.map(shellWord).join(" ")}` };
42
+ return { command: `${base} <${single ? "ticker" : placeholder ?? "tickers"}>${peers}`, search: `gloom search ${names.map(shellWord).join(" ")}` };
43
43
  }
44
44
  return { command: `${base} ${typed.length > 0 ? typed.map(shellWord).join(" ") : `<${placeholder ?? "ticker"}>`}${peers}`, search: null };
45
45
  }
@@ -52,14 +52,14 @@ function catalogHitCommand(hit: CatalogCommandHit, args: readonly string[]): { c
52
52
  const TICKER_SHAPED = /^\^?[A-Z0-9][A-Z0-9.=-]{0,11}(?::[A-Z0-9]{1,8})?$/;
53
53
 
54
54
  /**
55
- * What a ticker typed as a command (`gloomberb PLTR`) is answered with: the
55
+ * What a ticker typed as a command (`gloom PLTR`) is answered with: the
56
56
  * command that quotes it and the search that finds it. Null for a word not
57
57
  * written as a ticker.
58
58
  */
59
59
  export function tickerPointer(token: string): string | null {
60
60
  const word = token.trim();
61
61
  if (!TICKER_SHAPED.test(word) || !/[A-Z]/.test(word)) return null;
62
- return [`To quote it: gloomberb quote ${word}`, `Find the ticker: gloomberb search ${word}`].join("\n");
62
+ return [`To quote it: gloom quote ${word}`, `Find the ticker: gloom search ${word}`].join("\n");
63
63
  }
64
64
 
65
65
  /**
@@ -71,7 +71,7 @@ export function tickerPointer(token: string): string | null {
71
71
  export function catalogPointer(token: string, hits: readonly CatalogCommandHit[], args: readonly string[]): string | null {
72
72
  if (hits.length === 0) return null;
73
73
  const word = /^[\w.:-]+$/.test(token) ? token : JSON.stringify(token);
74
- const more = `gloomberb catalog ${word}`;
74
+ const more = `gloom catalog ${word}`;
75
75
  if (hits.length === 1) {
76
76
  const { command, search } = catalogHitCommand(hits[0]!, args);
77
77
  return `Try \`${command}\` (${hits[0]!.label})${search ? `; \`${search}\` finds the ticker` : ""}. \`${more}\` lists more.`;