gloomberb 0.16.4 → 0.16.6

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 (852) hide show
  1. package/README.md +14 -91
  2. package/package.json +5 -1
  3. package/src/{plugins/builtin/cloud → account}/auth-form.tsx +9 -9
  4. package/src/{plugins/builtin/cloud → account}/auth-model.ts +4 -4
  5. package/src/account/billing.ts +57 -0
  6. package/src/{plugins/builtin/cloud → account}/device-signin-dialog.tsx +18 -12
  7. package/src/{plugins/builtin/cloud → account}/device-signin.ts +2 -2
  8. package/src/{plugins/builtin/cloud → account}/email-auth-attempt.ts +2 -2
  9. package/src/account/session.ts +16 -0
  10. package/src/{plugins/builtin/cloud → account}/upgrade-dialog.tsx +16 -15
  11. package/src/{plugins/builtin/cloud → account}/upgrade-personalization.ts +7 -7
  12. package/src/{plugins/builtin/cloud → account}/upgrade-tickers.ts +6 -6
  13. package/src/{plugins/builtin/cloud → account}/verification-panel.tsx +6 -6
  14. package/src/api-client/central-bank-rates.ts +6 -1
  15. package/src/api-client/chat.ts +26 -0
  16. package/src/api-client/credit-boards.ts +2 -0
  17. package/src/api-client/data.ts +73 -3
  18. package/src/api-client/earnings.ts +6 -0
  19. package/src/api-client/europe-energy.ts +106 -0
  20. package/src/api-client/futures-curve.ts +56 -0
  21. package/src/api-client/index.ts +13 -1
  22. package/src/api-client/market-discovery.ts +13 -1
  23. package/src/api-client/normalizers.ts +32 -0
  24. package/src/api-client/paths.ts +7 -0
  25. package/src/api-client/perps.ts +8 -0
  26. package/src/api-client/request.ts +9 -2
  27. package/src/api-client/research-activity.ts +15 -10
  28. package/src/api-client/socket.ts +29 -0
  29. package/src/api-client/themes.ts +22 -1
  30. package/src/api-client/types.ts +78 -2
  31. package/src/api-client/yield-curves.ts +8 -0
  32. package/src/app/global-shortcuts.ts +50 -2
  33. package/src/app/keybindings/actions.ts +12 -1
  34. package/src/app/pane-runtime/plugin-bindings.ts +2 -2
  35. package/src/app/pane-runtime/ticker-open-runtime.ts +16 -6
  36. package/src/app/runtime/desktop-deeplink.ts +10 -5
  37. package/src/app/runtime/startup.ts +1 -1
  38. package/src/app.tsx +6 -0
  39. package/src/architecture/core-builtin-allowlist.json +8 -26
  40. package/src/ask-gloom/pane-context.ts +114 -0
  41. package/src/ask-gloom/pane-request.ts +70 -0
  42. package/src/ask-gloom/pane-text.ts +201 -0
  43. package/src/brokers/signed-in/sign-in-dialog.tsx +11 -5
  44. package/src/capabilities/chart-series.ts +19 -2
  45. package/src/capabilities/factories.ts +1 -0
  46. package/src/cli/central-bank-events.ts +23 -0
  47. package/src/cli/command-options.ts +17 -5
  48. package/src/cli/commands/crypto-hints.ts +35 -2
  49. package/src/cli/commands/fred-series.ts +146 -0
  50. package/src/cli/commands/market.ts +501 -115
  51. package/src/cli/commands/news-hints.ts +62 -0
  52. package/src/cli/commands/news-search.ts +53 -0
  53. package/src/cli/commands/options-leaps.ts +5 -2
  54. package/src/cli/commands/overview.ts +132 -26
  55. package/src/cli/commands/remote.ts +2 -1
  56. package/src/cli/commands/search.ts +317 -13
  57. package/src/cli/commands/system.ts +55 -8
  58. package/src/cli/commands/ticker.ts +155 -18
  59. package/src/cli/context.ts +45 -14
  60. package/src/cli/desktop-pane-shot.ts +76 -7
  61. package/src/cli/earnings-calendar.ts +71 -0
  62. package/src/cli/errors.ts +7 -5
  63. package/src/cli/exit-codes.ts +8 -0
  64. package/src/cli/export-source.ts +58 -0
  65. package/src/cli/freshness.ts +18 -7
  66. package/src/cli/glossary.ts +483 -0
  67. package/src/cli/help.ts +10 -0
  68. package/src/cli/helpers.ts +2 -5
  69. package/src/cli/history-rows.ts +118 -7
  70. package/src/cli/index-roots.ts +7 -0
  71. package/src/cli/index.ts +29 -9
  72. package/src/cli/known-gaps.ts +84 -0
  73. package/src/cli/listing-arg.ts +551 -97
  74. package/src/cli/not-a-ticker.ts +24 -9
  75. package/src/cli/pane-functions/access-gate.ts +13 -2
  76. package/src/cli/pane-functions/capabilities.ts +4 -3
  77. package/src/cli/pane-functions/catalog.ts +214 -40
  78. package/src/cli/pane-functions/data.ts +42 -8
  79. package/src/cli/pane-functions/discovery.ts +1 -0
  80. package/src/cli/pane-functions/dom.ts +37 -8
  81. package/src/cli/pane-functions/freshness.ts +393 -49
  82. package/src/cli/pane-functions/function-help.ts +31 -15
  83. package/src/cli/pane-functions/headless.ts +98 -30
  84. package/src/cli/pane-functions/index.ts +101 -19
  85. package/src/cli/pane-functions/market-session.ts +22 -8
  86. package/src/cli/pane-functions/options.ts +71 -22
  87. package/src/cli/pane-functions/report-notices.ts +25 -7
  88. package/src/cli/pane-functions/report.ts +15 -8
  89. package/src/cli/pane-functions/resolver.ts +74 -19
  90. package/src/cli/pane-functions/screenshot.ts +250 -27
  91. package/src/cli/perpetual-contract.ts +60 -0
  92. package/src/cli/registry.ts +3 -1
  93. package/src/cli/report-tables.ts +26 -7
  94. package/src/cli/result.ts +45 -11
  95. package/src/cli/series-search.ts +111 -0
  96. package/src/cli/staged-tickers.ts +52 -0
  97. package/src/cli/symbol-args.ts +27 -0
  98. package/src/cli/symbol-list.ts +154 -0
  99. package/src/cli/symbol-rows.ts +154 -0
  100. package/src/cli/ticker-resolution.ts +311 -27
  101. package/src/cli/types.ts +5 -0
  102. package/src/components/chart/composite/axis-overlays.tsx +14 -3
  103. package/src/components/chart/composite/composite-chart.tsx +71 -11
  104. package/src/components/chart/composite/crosshair-readout.tsx +150 -0
  105. package/src/components/chart/composite/downsample.ts +1 -1
  106. package/src/components/chart/composite/format.ts +29 -0
  107. package/src/components/chart/composite/interactions.ts +9 -2
  108. package/src/components/chart/composite/legend.tsx +100 -33
  109. package/src/components/chart/composite/panel-bitmap.ts +70 -35
  110. package/src/components/chart/composite/panel-labels.ts +18 -17
  111. package/src/components/chart/composite/panel-series.ts +1 -0
  112. package/src/components/chart/composite/panel-surface.tsx +46 -21
  113. package/src/components/chart/composite/price-axis-labels.tsx +3 -1
  114. package/src/components/chart/composite/rasterizer.ts +50 -8
  115. package/src/components/chart/composite/scene.ts +2 -1
  116. package/src/components/chart/composite/time-scale.ts +26 -9
  117. package/src/components/chart/composite/types.ts +18 -0
  118. package/src/components/chart/composite/use-composite-viewport.ts +30 -2
  119. package/src/components/chart/native/raster/crosshair.ts +8 -3
  120. package/src/components/chart/native/raster/primitives.ts +85 -21
  121. package/src/components/chart/native/surface/manager.ts +33 -8
  122. package/src/components/chart/surface3d/chart.tsx +1 -1
  123. package/src/components/command-bar/action-runtime.ts +1 -1
  124. package/src/components/command-bar/commands/collection-list.ts +210 -0
  125. package/src/components/command-bar/commands/collection.ts +40 -1
  126. package/src/components/command-bar/commands/direct/index.ts +4 -0
  127. package/src/components/command-bar/commands/registry.ts +8 -0
  128. package/src/components/command-bar/panel/index.tsx +11 -3
  129. package/src/components/command-bar/panel/runtime.ts +3 -0
  130. package/src/components/command-bar/panel/types.ts +2 -0
  131. package/src/components/command-bar/routes/root/plugin-install.ts +4 -4
  132. package/src/components/command-bar/routes/root/provider-search.ts +4 -3
  133. package/src/components/command-bar/routes/ticker-search/results.ts +12 -11
  134. package/src/components/command-bar/routes/ticker-search/route.ts +4 -3
  135. package/src/components/command-bar/routing/actions.ts +1 -1
  136. package/src/components/command-bar/workflow/tickers.ts +42 -17
  137. package/src/components/layout/detached-pane-shell.tsx +68 -39
  138. package/src/components/layout/floating-pane.tsx +10 -1
  139. package/src/components/layout/header.tsx +25 -5
  140. package/src/components/layout/missing-pane.tsx +3 -3
  141. package/src/components/layout/pane/capture-stamp.ts +41 -0
  142. package/src/components/layout/pane/capture-status.ts +12 -0
  143. package/src/components/layout/pane/content.tsx +7 -13
  144. package/src/components/layout/pane/footer/index.tsx +6 -2
  145. package/src/components/layout/pane/footer/keyboard.ts +3 -0
  146. package/src/components/layout/pane/footer/model.ts +41 -1
  147. package/src/components/layout/pane/header.tsx +50 -1
  148. package/src/components/layout/pane/index.tsx +21 -3
  149. package/src/components/layout/pane/sidebar.tsx +88 -21
  150. package/src/components/layout/shell/active-drag.ts +21 -5
  151. package/src/components/layout/shell/cursor-occlusion.ts +2 -1
  152. package/src/components/layout/shell/drag/index.ts +39 -9
  153. package/src/components/layout/shell/drag/live.ts +61 -51
  154. package/src/components/layout/shell/drag/runtime.ts +54 -12
  155. package/src/components/layout/shell/index.tsx +84 -65
  156. package/src/components/layout/shell/menu.ts +14 -1
  157. package/src/components/layout/shell/native/pointer-runtime.ts +3 -1
  158. package/src/components/layout/shell/pane/actions.ts +32 -10
  159. package/src/components/layout/shell/pane/ask.ts +131 -0
  160. package/src/components/layout/shell/pane/capture.ts +162 -0
  161. package/src/components/layout/shell/pane/layers.tsx +218 -50
  162. package/src/components/layout/shell/pane/management-shortcuts.ts +46 -1
  163. package/src/components/layout/shell/shortcuts.ts +21 -4
  164. package/src/components/layout/shell/terminal-pointer-runtime.ts +24 -0
  165. package/src/components/markdown-text.tsx +62 -20
  166. package/src/components/metric-treemap/heat-surface.tsx +8 -1
  167. package/src/components/onboarding/account-step/form-panel.tsx +1 -1
  168. package/src/components/onboarding/account-step/index.tsx +1 -1
  169. package/src/components/onboarding/account-step/qr-panel.tsx +1 -1
  170. package/src/components/onboarding/account-step/signed-in-panel.tsx +1 -1
  171. package/src/components/onboarding/onboarding-keyboard.ts +1 -1
  172. package/src/components/onboarding/onboarding-wizard.tsx +2 -2
  173. package/src/components/onboarding/use-onboarding-upgrade.ts +3 -3
  174. package/src/components/onboarding/wizard-account.ts +2 -2
  175. package/src/components/pane-template-wizard.tsx +9 -1
  176. package/src/components/price-selector-dialog.tsx +11 -2
  177. package/src/components/reader/article-reader.tsx +642 -0
  178. package/src/components/reader/article-text.ts +527 -0
  179. package/src/components/sign-in-gate.tsx +3 -3
  180. package/src/components/ticker/list-table-view.tsx +43 -2
  181. package/src/components/ui/action-row.tsx +2 -1
  182. package/src/components/ui/button.tsx +7 -1
  183. package/src/components/ui/choice-dialog.tsx +6 -4
  184. package/src/components/ui/confirm-dialog.tsx +28 -18
  185. package/src/components/ui/data-table/index.tsx +18 -6
  186. package/src/components/ui/data-table/opentui/index.tsx +37 -6
  187. package/src/components/ui/data-table/types.ts +12 -0
  188. package/src/components/ui/dialog-actions.tsx +64 -0
  189. package/src/components/ui/display.tsx +17 -3
  190. package/src/components/ui/frame.tsx +35 -2
  191. package/src/components/ui/icon.tsx +6 -1
  192. package/src/components/ui/query-bar.tsx +10 -1
  193. package/src/components/ui/text-prompt-dialog.tsx +11 -9
  194. package/src/data/cached-query.ts +2 -0
  195. package/src/data/config/store/migrations.ts +7 -0
  196. package/src/data/config/store/normalize.ts +7 -2
  197. package/src/data/config/store/portfolio-as-of-column.ts +57 -0
  198. package/src/data/ticker-repository.ts +5 -0
  199. package/src/data/ticker-store.ts +15 -0
  200. package/src/docs/content.ts +215 -0
  201. package/src/docs/load.ts +139 -0
  202. package/src/docs/requests.ts +39 -0
  203. package/src/docs/snapshot.chunk.ts +8 -0
  204. package/src/docs/snapshot.json +7555 -0
  205. package/src/docs/topics.ts +216 -0
  206. package/src/i18n/es.ts +65 -5
  207. package/src/i18n/ja.ts +65 -5
  208. package/src/i18n/ko.ts +65 -5
  209. package/src/i18n/zh-cn.ts +65 -5
  210. package/src/i18n/zh-tw.ts +65 -5
  211. package/src/layout/desks.ts +1 -1
  212. package/src/layout/pane-manager/dock-tree.ts +18 -0
  213. package/src/layout/pane-manager/index.ts +1 -0
  214. package/src/layout-marketplace/gallery.tsx +1 -1
  215. package/src/market-data/coordinator/chart.ts +10 -4
  216. package/src/market-data/coordinator/index.ts +6 -3
  217. package/src/{plugins/builtin/futures/contracts.ts → market-data/futures-board.ts} +81 -28
  218. package/src/market-data/futures-contract.ts +151 -0
  219. package/src/market-data/hooks.tsx +10 -2
  220. package/src/market-data/market/format.ts +39 -21
  221. package/src/market-data/market/freshness.ts +84 -20
  222. package/src/market-data/market/session-close-note.ts +3 -2
  223. package/src/market-data/market/status.ts +19 -23
  224. package/src/market-data/published-apac-sessions.ts +23 -1
  225. package/src/market-data/quotes/contributions.ts +5 -0
  226. package/src/market-data/quotes/metadata.ts +19 -24
  227. package/src/market-data/quotes/resolution.ts +5 -0
  228. package/src/market-data/quotes/screener-live-quotes.ts +5 -4
  229. package/src/market-data/result-types.ts +2 -0
  230. package/src/notifications/app-notifier.ts +17 -1
  231. package/src/notifications/notification-log.ts +180 -0
  232. package/src/plugins/auto-update-node.ts +2 -2
  233. package/src/plugins/auto-update.ts +2 -2
  234. package/src/plugins/builtin/account-management/index.tsx +1 -0
  235. package/src/plugins/builtin/account-management/model.ts +1 -56
  236. package/src/plugins/builtin/account-management/pane.tsx +6 -4
  237. package/src/plugins/builtin/account-management/password-dialog.tsx +1 -1
  238. package/src/plugins/builtin/alerts/catalysts.ts +1 -1
  239. package/src/plugins/builtin/alerts/cli.ts +313 -47
  240. package/src/plugins/builtin/alerts/events-pane.tsx +45 -7
  241. package/src/plugins/builtin/alerts/events.ts +23 -2
  242. package/src/plugins/builtin/alerts/focus.ts +27 -0
  243. package/src/plugins/builtin/alerts/history-pane.tsx +7 -2
  244. package/src/plugins/builtin/alerts/history.ts +2 -0
  245. package/src/plugins/builtin/alerts/index.tsx +47 -11
  246. package/src/plugins/builtin/alerts/pane.tsx +27 -1
  247. package/src/plugins/builtin/alerts/research-builder.ts +8 -3
  248. package/src/plugins/builtin/alerts/research-rules.ts +18 -2
  249. package/src/plugins/builtin/alerts/scheduled-check.ts +122 -0
  250. package/src/plugins/builtin/alerts/scheduled-sources.ts +25 -0
  251. package/src/plugins/builtin/alerts/scheduled.ts +254 -0
  252. package/src/plugins/builtin/alerts/targets.ts +92 -0
  253. package/src/plugins/builtin/analytics/index.tsx +8 -3
  254. package/src/plugins/builtin/analytics/risk-headless.ts +60 -27
  255. package/src/plugins/builtin/analytics/risk-math.ts +91 -27
  256. package/src/plugins/builtin/analytics/risk-model.ts +35 -5
  257. package/src/plugins/builtin/analytics/risk-pane.tsx +15 -8
  258. package/src/plugins/builtin/attention/headless.ts +1 -1
  259. package/src/plugins/builtin/attention/index.tsx +2 -0
  260. package/src/plugins/builtin/attention/pane.tsx +3 -1
  261. package/src/plugins/builtin/attention/series.ts +26 -0
  262. package/src/plugins/builtin/awards/headless.ts +88 -18
  263. package/src/plugins/builtin/awards/index.tsx +2 -0
  264. package/src/plugins/builtin/awards/model.ts +41 -1
  265. package/src/plugins/builtin/awards/pane.tsx +22 -13
  266. package/src/plugins/builtin/awards/series.ts +29 -0
  267. package/src/plugins/builtin/backtest/headless.ts +2 -2
  268. package/src/plugins/builtin/bond-calculator/model.ts +2 -1
  269. package/src/plugins/builtin/broker-manager/index.tsx +1 -0
  270. package/src/plugins/builtin/catalysts/headless.ts +1 -1
  271. package/src/plugins/builtin/catalysts/pane.tsx +3 -1
  272. package/src/plugins/builtin/cds/client.ts +49 -12
  273. package/src/plugins/builtin/cds/headless.ts +119 -19
  274. package/src/plugins/builtin/cds/index.tsx +3 -1
  275. package/src/plugins/builtin/cds/model.ts +214 -32
  276. package/src/plugins/builtin/cds/pane.tsx +58 -14
  277. package/src/plugins/builtin/cds/series.ts +19 -0
  278. package/src/plugins/builtin/central-bank-rates/client.ts +4 -0
  279. package/src/plugins/builtin/central-bank-rates/headless.ts +46 -16
  280. package/src/plugins/builtin/central-bank-rates/index.tsx +3 -1
  281. package/src/plugins/builtin/central-bank-rates/model.ts +99 -0
  282. package/src/plugins/builtin/central-bank-rates/pane.tsx +1 -1
  283. package/src/plugins/builtin/central-bank-rates/series.ts +36 -0
  284. package/src/plugins/builtin/chart-composer/catalog-inventory.ts +193 -255
  285. package/src/plugins/builtin/chart-composer/data-catalog-pane.tsx +84 -46
  286. package/src/plugins/builtin/chart-composer/editor.tsx +5 -4
  287. package/src/plugins/builtin/chart-composer/field-series.ts +40 -0
  288. package/src/plugins/builtin/chart-composer/headless-schema.ts +1 -1
  289. package/src/plugins/builtin/chart-composer/headless.ts +70 -5
  290. package/src/plugins/builtin/chart-composer/index.tsx +15 -3
  291. package/src/plugins/builtin/chart-composer/pane.tsx +81 -38
  292. package/src/plugins/builtin/chart-composer/series-catalog.ts +58 -50
  293. package/src/plugins/builtin/chart-composer/series-expression.ts +18 -10
  294. package/src/plugins/builtin/chart-composer/use-series-catalog.ts +59 -3
  295. package/src/plugins/builtin/chart-composer/user-series.ts +84 -0
  296. package/src/plugins/builtin/chat/content/composer-runtime.ts +6 -1
  297. package/src/plugins/builtin/chat/content/composer.tsx +5 -1
  298. package/src/plugins/builtin/chat/content/footer.tsx +12 -0
  299. package/src/plugins/builtin/chat/content/index.tsx +89 -5
  300. package/src/plugins/builtin/chat/content/new-dm-dialog.tsx +10 -2
  301. package/src/plugins/builtin/chat/content/new-messages.tsx +89 -0
  302. package/src/plugins/builtin/chat/content/row-activity.ts +132 -0
  303. package/src/plugins/builtin/chat/content/scroll.ts +127 -27
  304. package/src/plugins/builtin/chat/content/shortcuts.ts +2 -2
  305. package/src/plugins/builtin/chat/content/transcript.tsx +145 -78
  306. package/src/plugins/builtin/chat/content/types.ts +1 -0
  307. package/src/plugins/builtin/chat/controller/fetch.ts +8 -2
  308. package/src/plugins/builtin/chat/controller/index.ts +123 -1
  309. package/src/plugins/builtin/chat/controller/message-loading.ts +3 -0
  310. package/src/plugins/builtin/chat/controller/messages.ts +7 -2
  311. package/src/plugins/builtin/chat/controller/realtime.ts +10 -1
  312. package/src/plugins/builtin/chat/controller/send.ts +61 -1
  313. package/src/plugins/builtin/chat/controller/state.ts +8 -0
  314. package/src/plugins/builtin/chat/ghost-user.ts +20 -0
  315. package/src/plugins/builtin/chat/index.tsx +23 -5
  316. package/src/plugins/builtin/chat/layout.ts +78 -5
  317. package/src/plugins/builtin/chat/message/ai-badge.tsx +18 -0
  318. package/src/plugins/builtin/chat/message/desktop.tsx +55 -6
  319. package/src/plugins/builtin/chat/message/header.tsx +16 -4
  320. package/src/plugins/builtin/chat/message/profile-popover.tsx +5 -1
  321. package/src/plugins/builtin/chat/message/reactions.tsx +210 -0
  322. package/src/plugins/builtin/chat/message/render-state.ts +18 -2
  323. package/src/plugins/builtin/chat/message/terminal.tsx +43 -4
  324. package/src/plugins/builtin/chat/message/types.ts +12 -0
  325. package/src/plugins/builtin/chat/reactions.ts +197 -0
  326. package/src/plugins/builtin/chat/share/flow.tsx +87 -0
  327. package/src/plugins/builtin/chat/share/targets.ts +27 -0
  328. package/src/plugins/builtin/chat/status-widget.tsx +6 -3
  329. package/src/plugins/builtin/chat/unread-inbox-pane.tsx +148 -27
  330. package/src/plugins/builtin/chat/unread-inbox.ts +22 -0
  331. package/src/plugins/builtin/cloud/askg/attached-pane.tsx +69 -0
  332. package/src/plugins/builtin/cloud/askg/controller.ts +111 -19
  333. package/src/plugins/builtin/cloud/askg/executor.ts +57 -3
  334. package/src/plugins/builtin/cloud/askg/manifest.ts +32 -7
  335. package/src/plugins/builtin/cloud/askg/model.ts +27 -8
  336. package/src/plugins/builtin/cloud/askg/pane-attachment.ts +94 -0
  337. package/src/plugins/builtin/cloud/askg/pane.tsx +141 -12
  338. package/src/plugins/builtin/cloud/askg/pending-question.ts +11 -0
  339. package/src/plugins/builtin/cloud/askg/protocol.ts +10 -1
  340. package/src/plugins/builtin/cloud/askg/tool-display.ts +3 -0
  341. package/src/plugins/builtin/cloud/askg/undo.ts +2 -0
  342. package/src/plugins/builtin/cloud/auth-actions.tsx +1 -1
  343. package/src/plugins/builtin/cloud/auth-commands.ts +1 -1
  344. package/src/plugins/builtin/cloud/auth-dialog.tsx +3 -3
  345. package/src/plugins/builtin/cloud/company-picker.tsx +1 -1
  346. package/src/plugins/builtin/cloud/mcp-connect/dialog.tsx +3 -0
  347. package/src/plugins/builtin/cloud/plugin.tsx +19 -2
  348. package/src/plugins/builtin/cloud/team/model.ts +5 -0
  349. package/src/plugins/builtin/cloud/team/module.tsx +1 -0
  350. package/src/plugins/builtin/cloud/team/store.ts +8 -3
  351. package/src/plugins/builtin/cloud/terminal-relay/engine.ts +77 -9
  352. package/src/plugins/builtin/cloud/terminal-relay/manifest.ts +6 -1
  353. package/src/plugins/builtin/cloud/terminal-relay/policy.ts +9 -0
  354. package/src/plugins/builtin/cloud/terminal-relay/prompts.tsx +35 -11
  355. package/src/plugins/builtin/cloud/thesis/exposure.ts +1 -1
  356. package/src/plugins/builtin/cloud/thesis/module.tsx +1 -0
  357. package/src/plugins/builtin/cloud/thesis/prompts.tsx +2 -1
  358. package/src/plugins/builtin/company-attention/app-rank.tsx +1 -1
  359. package/src/plugins/builtin/company-attention/headless.ts +21 -7
  360. package/src/plugins/builtin/company-attention/index.tsx +2 -0
  361. package/src/plugins/builtin/company-attention/model.ts +26 -7
  362. package/src/plugins/builtin/company-attention/pane.tsx +12 -9
  363. package/src/plugins/builtin/company-attention/series.ts +52 -0
  364. package/src/plugins/builtin/company-kpis/headless.ts +97 -10
  365. package/src/plugins/builtin/company-kpis/model.ts +24 -2
  366. package/src/plugins/builtin/company-kpis/pane.tsx +17 -16
  367. package/src/plugins/builtin/composite-plugins.ts +19 -13
  368. package/src/plugins/builtin/connections/index.ts +1 -0
  369. package/src/plugins/builtin/cot/headless.ts +1 -1
  370. package/src/plugins/builtin/cot/index.tsx +3 -1
  371. package/src/plugins/builtin/cot/model.ts +40 -11
  372. package/src/plugins/builtin/cot/series.ts +27 -0
  373. package/src/plugins/builtin/cpi/headless.ts +3 -3
  374. package/src/plugins/builtin/credit-boards/cdx-pane.tsx +10 -1
  375. package/src/plugins/builtin/credit-boards/client.ts +6 -2
  376. package/src/plugins/builtin/credit-boards/headless.ts +108 -31
  377. package/src/plugins/builtin/credit-boards/index.tsx +2 -0
  378. package/src/plugins/builtin/credit-boards/model.ts +11 -1
  379. package/src/plugins/builtin/credit-boards/series.ts +66 -0
  380. package/src/plugins/builtin/credit-conditions/client.ts +12 -9
  381. package/src/plugins/builtin/credit-conditions/headless.ts +13 -2
  382. package/src/plugins/builtin/credit-conditions/index.tsx +18 -9
  383. package/src/plugins/builtin/credit-conditions/model.ts +19 -11
  384. package/src/plugins/builtin/credit-conditions/series.ts +16 -0
  385. package/src/plugins/builtin/credit-documents/headless.ts +33 -3
  386. package/src/plugins/builtin/credit-documents/pane.tsx +3 -1
  387. package/src/plugins/builtin/crypto-board/headless.ts +2 -3
  388. package/src/plugins/builtin/crypto-board/index.tsx +2 -0
  389. package/src/plugins/builtin/crypto-board/model.ts +12 -0
  390. package/src/plugins/builtin/crypto-board/pane.tsx +19 -12
  391. package/src/plugins/builtin/crypto-board/series.ts +48 -0
  392. package/src/plugins/builtin/custom-view/live-quotes.ts +2 -2
  393. package/src/plugins/builtin/debt-maturities/headless.ts +17 -11
  394. package/src/plugins/builtin/debt-maturities/index.tsx +2 -0
  395. package/src/plugins/builtin/debt-maturities/series.ts +45 -0
  396. package/src/plugins/builtin/dividend-yield/client.ts +3 -0
  397. package/src/plugins/builtin/dividend-yield/headless.ts +7 -4
  398. package/src/plugins/builtin/dividend-yield/index.tsx +3 -1
  399. package/src/plugins/builtin/dividend-yield/pane.tsx +3 -1
  400. package/src/plugins/builtin/dividend-yield/series.ts +20 -0
  401. package/src/plugins/builtin/dividend-yield/types.ts +2 -0
  402. package/src/plugins/builtin/docs/blocks.tsx +181 -0
  403. package/src/plugins/builtin/docs/index.tsx +68 -0
  404. package/src/plugins/builtin/docs/pane.tsx +426 -0
  405. package/src/plugins/builtin/docs/targets.ts +72 -0
  406. package/src/plugins/builtin/docs/use-docs.ts +60 -0
  407. package/src/plugins/builtin/doe/headless.ts +12 -8
  408. package/src/plugins/builtin/doe/index.tsx +2 -0
  409. package/src/plugins/builtin/doe/series.ts +62 -0
  410. package/src/plugins/builtin/earnings/client.ts +3 -2
  411. package/src/plugins/builtin/earnings/format.ts +1 -5
  412. package/src/plugins/builtin/earnings/headless.ts +58 -6
  413. package/src/plugins/builtin/earnings/history-model.ts +15 -1
  414. package/src/plugins/builtin/earnings/history-table.ts +13 -2
  415. package/src/plugins/builtin/earnings/history.tsx +7 -3
  416. package/src/plugins/builtin/earnings/index.tsx +9 -0
  417. package/src/plugins/builtin/earnings-calls/headless.ts +28 -2
  418. package/src/plugins/builtin/earnings-calls/index.tsx +1 -1
  419. package/src/plugins/builtin/earnings-ripple/index.tsx +2 -0
  420. package/src/plugins/builtin/econ/fred-catalog.ts +198 -0
  421. package/src/plugins/builtin/econ/fred-series-map.ts +0 -46
  422. package/src/plugins/builtin/econ/index.tsx +2 -0
  423. package/src/plugins/builtin/econ-statistics/defs.ts +5 -0
  424. package/src/plugins/builtin/econ-statistics/headless.ts +19 -4
  425. package/src/plugins/builtin/econ-statistics/stats.ts +1 -0
  426. package/src/plugins/builtin/equity-screener/headless.ts +3 -3
  427. package/src/plugins/builtin/equity-screener/pane.tsx +4 -11
  428. package/src/plugins/builtin/estimate-revisions/headless.ts +3 -3
  429. package/src/plugins/builtin/exposure/drivers.ts +13 -0
  430. package/src/plugins/builtin/exposure/headless.ts +205 -13
  431. package/src/plugins/builtin/exposure/holdings.ts +1 -1
  432. package/src/plugins/builtin/exposure/index.tsx +1 -0
  433. package/src/plugins/builtin/exposure/model.ts +23 -3
  434. package/src/plugins/builtin/exposure/pane.tsx +14 -12
  435. package/src/plugins/builtin/fear-greed/index.tsx +18 -10
  436. package/src/plugins/builtin/fear-greed/series.ts +52 -0
  437. package/src/plugins/builtin/futures/index.tsx +43 -3
  438. package/src/plugins/builtin/futures/model.ts +1 -1
  439. package/src/plugins/builtin/futures/returns.ts +1 -1
  440. package/src/plugins/builtin/futures/series.ts +13 -0
  441. package/src/plugins/builtin/futures/table.tsx +1 -1
  442. package/src/plugins/builtin/futures/use-front-returns.ts +1 -1
  443. package/src/plugins/builtin/futures-curve/client.ts +12 -3
  444. package/src/plugins/builtin/futures-curve/headless.ts +71 -10
  445. package/src/plugins/builtin/futures-curve/index.tsx +1 -1
  446. package/src/plugins/builtin/futures-curve/model.ts +66 -11
  447. package/src/plugins/builtin/futures-curve/pane.tsx +52 -18
  448. package/src/plugins/builtin/fx-matrix/client.ts +63 -0
  449. package/src/plugins/builtin/fx-matrix/export.ts +2 -1
  450. package/src/plugins/builtin/fx-matrix/headless.ts +154 -0
  451. package/src/plugins/builtin/fx-matrix/index.tsx +4 -4
  452. package/src/plugins/builtin/gpu/board.tsx +13 -10
  453. package/src/plugins/builtin/gpu/changes.tsx +4 -4
  454. package/src/plugins/builtin/gpu/client.ts +19 -1
  455. package/src/plugins/builtin/gpu/equities.tsx +14 -10
  456. package/src/plugins/builtin/gpu/headless.ts +58 -27
  457. package/src/plugins/builtin/gpu/history.tsx +3 -3
  458. package/src/plugins/builtin/gpu/index.tsx +2 -0
  459. package/src/plugins/builtin/gpu/model.ts +101 -16
  460. package/src/plugins/builtin/gpu/pane.tsx +28 -12
  461. package/src/plugins/builtin/gpu/series.ts +38 -0
  462. package/src/plugins/builtin/help/function-card.tsx +25 -6
  463. package/src/plugins/builtin/help/function-index.ts +2 -0
  464. package/src/plugins/builtin/help/index.tsx +31 -9
  465. package/src/plugins/builtin/holders/beneficial-model.ts +90 -3
  466. package/src/plugins/builtin/holders/beneficial-report.ts +57 -5
  467. package/src/plugins/builtin/holders/beneficial-view.tsx +55 -11
  468. package/src/plugins/builtin/holders/client.ts +22 -3
  469. package/src/plugins/builtin/holders/format.ts +18 -3
  470. package/src/plugins/builtin/holders/headless.ts +36 -133
  471. package/src/plugins/builtin/holders/pane.tsx +11 -4
  472. package/src/plugins/builtin/holders/report-header.ts +40 -5
  473. package/src/plugins/builtin/holders/report-rows.ts +240 -0
  474. package/src/plugins/builtin/insider/client.ts +35 -20
  475. package/src/plugins/builtin/insider/headless.ts +41 -11
  476. package/src/plugins/builtin/insider/index.tsx +26 -9
  477. package/src/plugins/builtin/insider/insider-data.ts +10 -0
  478. package/src/plugins/builtin/insider/issuer.ts +49 -0
  479. package/src/plugins/builtin/insider/model.ts +3 -0
  480. package/src/plugins/builtin/ipo-calendar/headless.ts +1 -1
  481. package/src/plugins/builtin/iv-history/client.ts +20 -6
  482. package/src/plugins/builtin/iv-history/format.ts +9 -0
  483. package/src/plugins/builtin/iv-history/headless.ts +56 -21
  484. package/src/plugins/builtin/iv-history/index.tsx +2 -0
  485. package/src/plugins/builtin/iv-history/model.ts +143 -8
  486. package/src/plugins/builtin/iv-history/screen-pane.tsx +5 -9
  487. package/src/plugins/builtin/iv-history/series.ts +29 -0
  488. package/src/plugins/builtin/jobs/headless.ts +26 -3
  489. package/src/plugins/builtin/jobs/index.tsx +3 -1
  490. package/src/plugins/builtin/jobs/series.ts +19 -0
  491. package/src/plugins/builtin/kelly-sizer/index.tsx +2 -0
  492. package/src/plugins/builtin/kelly-sizer/pane.tsx +2 -1
  493. package/src/plugins/builtin/kelly-sizer/portfolio.ts +0 -39
  494. package/src/plugins/builtin/macro-day/client.ts +44 -3
  495. package/src/plugins/builtin/macro-day/headless.ts +13 -10
  496. package/src/plugins/builtin/macro-day/model.ts +56 -10
  497. package/src/plugins/builtin/macro-day/pane.tsx +30 -20
  498. package/src/plugins/builtin/market-heatmap/headless.ts +20 -5
  499. package/src/plugins/builtin/market-heatmap/index.tsx +6 -0
  500. package/src/plugins/builtin/market-heatmap/model.ts +19 -11
  501. package/src/plugins/builtin/market-heatmap/portfolio.ts +2 -2
  502. package/src/plugins/builtin/market-movers/client.ts +7 -5
  503. package/src/plugins/builtin/market-movers/index.tsx +3 -2
  504. package/src/plugins/builtin/market-movers/model.ts +30 -0
  505. package/src/plugins/builtin/market-movers/screener.ts +31 -0
  506. package/src/plugins/builtin/market-valuation/chart-series.ts +29 -69
  507. package/src/plugins/builtin/market-valuation/index.tsx +3 -3
  508. package/src/plugins/builtin/market-valuation/indicators.ts +0 -5
  509. package/src/plugins/builtin/members/headless.ts +8 -3
  510. package/src/plugins/builtin/members/model.ts +31 -3
  511. package/src/plugins/builtin/members/pane.tsx +6 -8
  512. package/src/plugins/builtin/mna/distress/headless.ts +4 -4
  513. package/src/plugins/builtin/mna/headless.ts +18 -6
  514. package/src/plugins/builtin/money-markets/headless.ts +5 -4
  515. package/src/plugins/builtin/money-markets/index.tsx +2 -0
  516. package/src/plugins/builtin/money-markets/series.ts +41 -0
  517. package/src/plugins/builtin/news/index.tsx +0 -2
  518. package/src/plugins/builtin/news/wire/news/detail-view.tsx +53 -104
  519. package/src/plugins/builtin/news/wire/news/footer.ts +2 -25
  520. package/src/plugins/builtin/news/wire/news/preset-pane.tsx +0 -2
  521. package/src/plugins/builtin/notes/cli.ts +12 -7
  522. package/src/plugins/builtin/notes/index.tsx +1 -0
  523. package/src/plugins/builtin/options/index.tsx +3 -0
  524. package/src/plugins/builtin/options/view.tsx +1 -1
  525. package/src/plugins/builtin/options-calculator/inputs.ts +2 -1
  526. package/src/plugins/builtin/options-positioning/client.ts +7 -3
  527. package/src/plugins/builtin/options-positioning/headless.ts +4 -3
  528. package/src/plugins/builtin/options-positioning/pane.tsx +2 -2
  529. package/src/plugins/builtin/options-scenario/client.ts +2 -1
  530. package/src/plugins/builtin/options-scenario/headless.ts +1 -0
  531. package/src/plugins/builtin/options-scenario/hedge.ts +2 -1
  532. package/src/plugins/builtin/perps/client.ts +90 -16
  533. package/src/plugins/builtin/perps/equity-row.tsx +52 -17
  534. package/src/plugins/builtin/perps/freshness.ts +66 -0
  535. package/src/plugins/builtin/perps/headless.ts +47 -32
  536. package/src/plugins/builtin/perps/index.tsx +23 -4
  537. package/src/plugins/builtin/perps/list-perpetuals.ts +118 -0
  538. package/src/plugins/builtin/perps/model.ts +20 -5
  539. package/src/plugins/builtin/perps/open-market.ts +15 -0
  540. package/src/plugins/builtin/perps/pane.tsx +76 -20
  541. package/src/plugins/builtin/perps/series.ts +76 -0
  542. package/src/plugins/builtin/plugin-marketplace/index.tsx +1 -1
  543. package/src/plugins/builtin/plugin-marketplace/pane.tsx +73 -67
  544. package/src/plugins/builtin/plugin-module.ts +3 -0
  545. package/src/plugins/builtin/portfolio-list/account-metrics.ts +1 -1
  546. package/src/plugins/builtin/portfolio-list/allocation.ts +5 -4
  547. package/src/plugins/builtin/portfolio-list/cell-version.ts +8 -1
  548. package/src/plugins/builtin/portfolio-list/cli/bulk-symbols.ts +161 -0
  549. package/src/plugins/builtin/portfolio-list/cli/import-13f.ts +109 -0
  550. package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +384 -74
  551. package/src/plugins/builtin/portfolio-list/cli/render.ts +437 -71
  552. package/src/plugins/builtin/portfolio-list/cli/shared.ts +21 -4
  553. package/src/plugins/builtin/portfolio-list/cli/watchlist-command.ts +121 -47
  554. package/src/plugins/builtin/portfolio-list/column-values.ts +104 -26
  555. package/src/plugins/builtin/portfolio-list/grid.tsx +1 -1
  556. package/src/plugins/builtin/portfolio-list/headless.ts +84 -18
  557. package/src/plugins/builtin/portfolio-list/imported-from.ts +8 -0
  558. package/src/plugins/builtin/portfolio-list/index.tsx +5 -1
  559. package/src/plugins/builtin/portfolio-list/live-valuation.ts +6 -2
  560. package/src/plugins/builtin/portfolio-list/mutations.ts +2 -9
  561. package/src/plugins/builtin/portfolio-list/pane/data.ts +5 -1
  562. package/src/plugins/builtin/portfolio-list/pane/index.tsx +52 -9
  563. package/src/plugins/builtin/portfolio-list/quick-add/index.tsx +33 -11
  564. package/src/plugins/builtin/portfolio-list/quick-add/resolution.ts +21 -1
  565. package/src/plugins/builtin/portfolio-list/settings.ts +17 -0
  566. package/src/plugins/builtin/portfolio-list/summary/index.tsx +12 -0
  567. package/src/plugins/builtin/portfolio-list/summary/totals.ts +9 -4
  568. package/src/plugins/builtin/portfolio-list/table.tsx +37 -7
  569. package/src/plugins/builtin/power/client.ts +16 -0
  570. package/src/plugins/builtin/power/evidence.ts +63 -10
  571. package/src/plugins/builtin/power/headless.ts +77 -9
  572. package/src/plugins/builtin/power/index.tsx +28 -3
  573. package/src/plugins/builtin/power/model.ts +73 -2
  574. package/src/plugins/builtin/power/pane.tsx +37 -9
  575. package/src/plugins/builtin/power/prices-client.ts +139 -0
  576. package/src/plugins/builtin/power/prices-headless.ts +137 -0
  577. package/src/plugins/builtin/power/prices-model.ts +103 -0
  578. package/src/plugins/builtin/power/prices.tsx +179 -0
  579. package/src/plugins/builtin/rate-path/headless.ts +46 -18
  580. package/src/plugins/builtin/realized-vol/headless.ts +5 -0
  581. package/src/plugins/builtin/relative-rotation/headless.ts +3 -3
  582. package/src/plugins/builtin/research/corporate-actions-pane.tsx +5 -2
  583. package/src/plugins/builtin/research/event-model.ts +68 -24
  584. package/src/plugins/builtin/research/events-headless.ts +2 -1
  585. package/src/plugins/builtin/research/headless.ts +2 -1
  586. package/src/plugins/builtin/research/index.tsx +2 -0
  587. package/src/plugins/builtin/research-search/article.ts +65 -0
  588. package/src/plugins/builtin/research-search/document-view.tsx +33 -215
  589. package/src/plugins/builtin/research-search/model.ts +0 -9
  590. package/src/plugins/builtin/research-search/pane.tsx +41 -30
  591. package/src/plugins/builtin/research-search/snippet.ts +0 -29
  592. package/src/plugins/builtin/revenue-breakdown/headless.ts +18 -6
  593. package/src/plugins/builtin/seasonality/client.ts +15 -7
  594. package/src/plugins/builtin/seasonality/headless.ts +36 -12
  595. package/src/plugins/builtin/seasonality/index.tsx +2 -2
  596. package/src/plugins/builtin/seasonality/model.ts +119 -0
  597. package/src/plugins/builtin/seasonality/pane.tsx +108 -37
  598. package/src/plugins/builtin/sec/headless.ts +25 -3
  599. package/src/plugins/builtin/sec/index.tsx +2 -1
  600. package/src/plugins/builtin/series-inventory.ts +93 -0
  601. package/src/plugins/builtin/shared/cloud-denied.ts +15 -0
  602. package/src/plugins/builtin/shared/cloud-upgrade.ts +1 -1
  603. package/src/plugins/builtin/shared/command-tab.ts +30 -12
  604. package/src/plugins/builtin/shared/earnings-report.ts +55 -0
  605. package/src/plugins/builtin/shared/fred-points.ts +20 -0
  606. package/src/plugins/builtin/shared/free-preview.ts +47 -0
  607. package/src/plugins/builtin/shared/fx-rate-freshness.ts +101 -0
  608. package/src/plugins/builtin/shared/open-description.ts +29 -0
  609. package/src/plugins/builtin/shared/report-freshness.ts +12 -1
  610. package/src/plugins/builtin/shared/series-warning.ts +5 -0
  611. package/src/plugins/builtin/shared/volatility/options.ts +4 -1
  612. package/src/plugins/builtin/short-interest/headless.ts +1 -0
  613. package/src/plugins/builtin/short-interest/index.tsx +2 -0
  614. package/src/plugins/builtin/short-interest/series.ts +36 -0
  615. package/src/plugins/builtin/short-interest/watch-headless.ts +3 -2
  616. package/src/plugins/builtin/short-interest/watch-model.ts +9 -5
  617. package/src/plugins/builtin/short-volume/headless.ts +2 -1
  618. package/src/plugins/builtin/short-volume/index.tsx +2 -0
  619. package/src/plugins/builtin/short-volume/series.ts +23 -0
  620. package/src/plugins/builtin/social-mentions/headless.ts +1 -1
  621. package/src/plugins/builtin/social-mentions/index.tsx +2 -0
  622. package/src/plugins/builtin/social-mentions/series.ts +23 -0
  623. package/src/plugins/builtin/supply-chain/graph-pane.tsx +3 -2
  624. package/src/plugins/builtin/supply-chain/headless.ts +43 -11
  625. package/src/plugins/builtin/supply-chain/model.ts +13 -0
  626. package/src/plugins/builtin/supply-chain/pane.tsx +8 -6
  627. package/src/plugins/builtin/themes/headless.ts +74 -10
  628. package/src/plugins/builtin/themes/model.ts +71 -4
  629. package/src/plugins/builtin/themes/pane.tsx +22 -5
  630. package/src/plugins/builtin/thirteenf/api.ts +1 -0
  631. package/src/plugins/builtin/thirteenf/data.ts +6 -4
  632. package/src/plugins/builtin/thirteenf/headless.ts +217 -36
  633. package/src/plugins/builtin/thirteenf/model.ts +39 -1
  634. package/src/plugins/builtin/thirteenf/overlap.ts +75 -0
  635. package/src/plugins/builtin/thirteenf/pane.tsx +10 -1
  636. package/src/plugins/builtin/thirteenf/report-notes.ts +103 -1
  637. package/src/plugins/builtin/thirteenf/types.ts +2 -0
  638. package/src/plugins/builtin/ticker-detail/data-panes/returns-history.ts +114 -0
  639. package/src/plugins/builtin/ticker-detail/data-panes/returns-model.ts +57 -2
  640. package/src/plugins/builtin/ticker-detail/data-panes/returns-pane.tsx +19 -55
  641. package/src/plugins/builtin/ticker-detail/headless-schema.ts +30 -0
  642. package/src/plugins/builtin/ticker-detail/headless.ts +86 -0
  643. package/src/plugins/builtin/ticker-detail/index.tsx +26 -11
  644. package/src/plugins/builtin/ticker-detail/overview/components.tsx +1 -1
  645. package/src/plugins/builtin/ticker-detail/overview/futures-contract.ts +31 -0
  646. package/src/plugins/builtin/ticker-detail/overview/model.ts +3 -3
  647. package/src/plugins/builtin/ticker-detail/overview/pane.tsx +2 -1
  648. package/src/plugins/builtin/ticker-detail/overview-tab.tsx +49 -5
  649. package/src/plugins/builtin/ticker-detail/quote-monitor/index.tsx +13 -3
  650. package/src/plugins/builtin/time-sales/headless.ts +2 -1
  651. package/src/plugins/builtin/time-sales/index.tsx +2 -1
  652. package/src/plugins/builtin/treasury-auctions/headless.ts +16 -2
  653. package/src/plugins/builtin/treasury-auctions/index.tsx +1 -0
  654. package/src/plugins/builtin/treasury-auctions/model.ts +8 -0
  655. package/src/plugins/builtin/vol-surface/evidence.ts +7 -1
  656. package/src/plugins/builtin/vol-surface/headless.ts +51 -17
  657. package/src/plugins/builtin/vol-surface/heat-grid.tsx +113 -0
  658. package/src/plugins/builtin/vol-surface/model.ts +39 -6
  659. package/src/plugins/builtin/vol-surface/pane.tsx +14 -13
  660. package/src/plugins/builtin/vol-surface/stored.ts +63 -3
  661. package/src/plugins/builtin/vol-surface/surface.tsx +30 -2
  662. package/src/plugins/builtin/volatility/index.tsx +2 -0
  663. package/src/plugins/builtin/volatility/series.ts +84 -0
  664. package/src/plugins/builtin/world-venue-map/basemap-layer.tsx +6 -5
  665. package/src/plugins/builtin/world-venue-map/basemap.ts +6 -3
  666. package/src/plugins/builtin/world-venue-map/geo-draw.tsx +2 -1
  667. package/src/plugins/builtin/world-venue-map/geo-series.ts +26 -1
  668. package/src/plugins/builtin/world-venue-map/geo-svg.tsx +6 -6
  669. package/src/plugins/builtin/world-venue-map/headless.ts +4 -1
  670. package/src/plugins/builtin/world-venue-map/index.ts +2 -1
  671. package/src/plugins/builtin/world-venue-map/layered-pane.tsx +24 -13
  672. package/src/plugins/builtin/world-venue-map/layers.ts +29 -0
  673. package/src/plugins/builtin/world-venue-map/map.tsx +144 -13
  674. package/src/plugins/builtin/world-venue-map/model.ts +56 -19
  675. package/src/plugins/builtin/world-venue-map/pane.tsx +5 -2
  676. package/src/plugins/builtin/yield-curve/chart.ts +2 -2
  677. package/src/plugins/builtin/yield-curve/curves.ts +21 -8
  678. package/src/plugins/builtin/yield-curve/headless.ts +71 -18
  679. package/src/plugins/builtin/yield-curve/index.tsx +4 -2
  680. package/src/plugins/builtin/yield-curve/series.ts +86 -0
  681. package/src/plugins/catalog-browser.ts +2 -1
  682. package/src/plugins/installer.ts +2 -2
  683. package/src/plugins/loader.ts +15 -0
  684. package/src/plugins/manager-node.ts +1 -1
  685. package/src/plugins/{builtin/plugin-marketplace → marketplace}/feed.ts +2 -2
  686. package/src/plugins/{builtin/plugin-marketplace → marketplace}/model.ts +6 -6
  687. package/src/plugins/{builtin/plugin-marketplace → marketplace}/store.ts +1 -1
  688. package/src/plugins/registry/host-actions.ts +11 -0
  689. package/src/plugins/registry/index.ts +89 -4
  690. package/src/portfolio/collection-name.ts +31 -0
  691. package/src/{plugins/builtin/portfolio-list → portfolio}/position-metrics.ts +6 -6
  692. package/src/portfolio/position-value.ts +40 -0
  693. package/src/portfolio/valuation-basis.ts +79 -0
  694. package/src/public/__snapshots__/public-api.test.ts.snap +7 -0
  695. package/src/public/time-series.ts +17 -0
  696. package/src/react/auto-refresh.ts +13 -3
  697. package/src/react/input.ts +33 -1
  698. package/src/react/key-repeat.ts +86 -0
  699. package/src/remote/app-host.tsx +20 -4
  700. package/src/remote/confirm-change.tsx +85 -0
  701. package/src/remote/controller-utils.ts +8 -1
  702. package/src/remote/controller.ts +144 -7
  703. package/src/remote/pane-screenshot.ts +47 -0
  704. package/src/remote/schema.ts +65 -2
  705. package/src/remote/types.ts +30 -0
  706. package/src/remote/watchlist.ts +306 -0
  707. package/src/renderers/browser/main.tsx +4 -3
  708. package/src/renderers/browser/research-entry.ts +4 -2
  709. package/src/renderers/cloudflare/worker.ts +1 -1
  710. package/src/renderers/dom/data-table/frozen-column.ts +3 -1
  711. package/src/renderers/dom/data-table/index.tsx +33 -6
  712. package/src/renderers/dom/data-table/row.tsx +30 -1
  713. package/src/renderers/dom/desktop/control-styles.ts +63 -1
  714. package/src/renderers/dom/desktop/controls.tsx +30 -23
  715. package/src/renderers/dom/desktop/dialog-actions.tsx +170 -0
  716. package/src/renderers/dom/desktop/icons.tsx +16 -0
  717. package/src/renderers/dom/dom-ui-host.tsx +3 -0
  718. package/src/renderers/dom/host/block-glyph-canvas.tsx +6 -3
  719. package/src/renderers/dom/host/box.tsx +8 -0
  720. package/src/renderers/dom/host/chart-surface.tsx +33 -2
  721. package/src/renderers/dom/host/live-frame.ts +6 -2
  722. package/src/renderers/dom/host/overflow-fade.ts +14 -1
  723. package/src/renderers/dom/host/scroll-box.tsx +32 -0
  724. package/src/renderers/dom/host/size-observer.ts +41 -0
  725. package/src/renderers/dom/host/sticky-scroll.ts +128 -0
  726. package/src/renderers/dom/host/style.ts +1 -1
  727. package/src/renderers/dom/host/surface-3d.tsx +19 -7
  728. package/src/renderers/dom/host/surface-fit.ts +406 -0
  729. package/src/renderers/dom/host/text.tsx +1 -1
  730. package/src/renderers/dom/input-host.tsx +1 -0
  731. package/src/renderers/dom/styles.css +102 -5
  732. package/src/renderers/electrobun/bun/application-menu/click.ts +18 -0
  733. package/src/renderers/electrobun/bun/index.ts +3 -2
  734. package/src/renderers/electrobun/shared/protocol.ts +1 -1
  735. package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +29 -2
  736. package/src/renderers/electrobun/view/cli-pane-shot-frame.tsx +63 -20
  737. package/src/renderers/electrobun/view/cli-pane-shot-health.ts +10 -26
  738. package/src/renderers/electrobun/view/main.tsx +5 -3
  739. package/src/renderers/electrobun/view/remote/asset-data-client.ts +2 -0
  740. package/src/renderers/opentui/chart-surface.tsx +1 -0
  741. package/src/renderers/opentui/frame-capture.ts +33 -0
  742. package/src/renderers/opentui/host.tsx +10 -13
  743. package/src/renderers/opentui/pane-image/glyphs-license.txt +107 -0
  744. package/src/renderers/opentui/pane-image/glyphs.json +1 -0
  745. package/src/renderers/opentui/pane-image/index.ts +107 -0
  746. package/src/renderers/opentui/pane-image/raster.ts +428 -0
  747. package/src/renderers/opentui/start.tsx +3 -3
  748. package/src/renderers/opentui/test-utils.tsx +3 -0
  749. package/src/renderers/opentui/ui-host.tsx +29 -1
  750. package/src/series/capability.ts +75 -0
  751. package/src/series/csv.ts +160 -0
  752. package/src/series/files.ts +107 -0
  753. package/src/series/registry.ts +198 -0
  754. package/src/series/resolve.ts +108 -0
  755. package/src/series/standalone.ts +48 -0
  756. package/src/series/types.ts +153 -0
  757. package/src/series/validate.ts +171 -0
  758. package/src/shares/chat.ts +34 -0
  759. package/src/shares/dialog.tsx +295 -0
  760. package/src/shares/flow.tsx +56 -0
  761. package/src/shares/live.ts +14 -22
  762. package/src/shares/pane-image.ts +152 -0
  763. package/src/shares/personal-pane.ts +64 -0
  764. package/src/shares/portable-layout.ts +4 -2
  765. package/src/shares/prepare.ts +20 -0
  766. package/src/sources/gloomberb-cloud/index.ts +109 -10
  767. package/src/sources/gloomberb-cloud/normalizers.ts +3 -0
  768. package/src/sources/gloomberb-cloud/perpetuals.ts +249 -0
  769. package/src/sources/history-result.ts +1 -0
  770. package/src/sources/history-retention.ts +11 -0
  771. package/src/sources/listing-symbols.ts +4 -1
  772. package/src/sources/listing-target.ts +4 -0
  773. package/src/sources/provider-router/batches.ts +4 -1
  774. package/src/sources/provider-router/cache.ts +4 -2
  775. package/src/sources/provider-router/cached-routes.ts +1 -1
  776. package/src/sources/provider-router/financial-routes.ts +1 -0
  777. package/src/sources/provider-router/financials.ts +13 -0
  778. package/src/sources/provider-router/history.ts +43 -25
  779. package/src/sources/provider-router/index.ts +14 -0
  780. package/src/sources/provider-router/search.ts +1 -0
  781. package/src/state/hooks/inline-tickers.ts +49 -11
  782. package/src/sync/core-contributors.ts +1 -0
  783. package/src/test-support/shell-pane-keys.tsx +1 -0
  784. package/src/theme/theme-context.tsx +15 -1
  785. package/src/tickers/company-name.ts +75 -0
  786. package/src/tickers/instrument-kind.ts +34 -1
  787. package/src/tickers/listing-name.ts +34 -0
  788. package/src/tickers/listing-venues.ts +132 -0
  789. package/src/tickers/open-target.ts +13 -4
  790. package/src/tickers/perpetual-listing.ts +151 -0
  791. package/src/tickers/prediction-listing.ts +26 -0
  792. package/src/tickers/search/index.ts +72 -11
  793. package/src/tickers/search/ranking.ts +98 -20
  794. package/src/tickers/search/types.ts +7 -1
  795. package/src/tickers/ticker-changes.ts +213 -0
  796. package/src/tickers/us-listing.ts +34 -0
  797. package/src/time-series/economic.ts +2 -6
  798. package/src/time-series/hooks.ts +9 -0
  799. package/src/time-series/ice-credit.ts +39 -0
  800. package/src/time-series/resolve.ts +211 -29
  801. package/src/time-series/studies.ts +1 -0
  802. package/src/time-series/types.ts +12 -2
  803. package/src/time-series/use-chart-resolution.ts +32 -0
  804. package/src/types/config.ts +10 -2
  805. package/src/types/data-provider.ts +11 -0
  806. package/src/types/financials.ts +62 -1
  807. package/src/types/headless.ts +113 -0
  808. package/src/types/instrument.ts +4 -0
  809. package/src/types/plugin.ts +52 -2
  810. package/src/types/price-history.ts +7 -0
  811. package/src/types/ticker-changes.ts +26 -0
  812. package/src/types/ticker.ts +14 -0
  813. package/src/ui/context-menu.tsx +13 -1
  814. package/src/ui/host.tsx +57 -3
  815. package/src/ui/live-resize.ts +91 -0
  816. package/src/ui/live-stretch.ts +153 -0
  817. package/src/ui/measured-cells.ts +58 -0
  818. package/src/ui/sticky-scroll.ts +7 -0
  819. package/src/utils/basis-points.ts +17 -0
  820. package/src/utils/central-banks.ts +76 -0
  821. package/src/utils/cli-output.ts +131 -15
  822. package/src/utils/concurrency.ts +25 -0
  823. package/src/utils/crypto-pair.ts +20 -0
  824. package/src/utils/currency-pair.ts +19 -0
  825. package/src/utils/currency-units.ts +11 -0
  826. package/src/utils/datetime-format.ts +27 -6
  827. package/src/utils/decimal-comma.ts +19 -0
  828. package/src/utils/dom-screenshot-css.ts +265 -0
  829. package/src/utils/dom-screenshot-rasters.ts +276 -0
  830. package/src/utils/dom-screenshot.ts +439 -52
  831. package/src/utils/double-escape-close.ts +15 -1
  832. package/src/utils/exchange-rate-snapshot.ts +6 -2
  833. package/src/utils/exchanges.ts +143 -1
  834. package/src/utils/format.ts +35 -5
  835. package/src/utils/forward-dividend.ts +14 -0
  836. package/src/utils/fundamentals.ts +66 -0
  837. package/src/utils/futures-generic.ts +6 -12
  838. package/src/utils/fx-market-hours.ts +15 -5
  839. package/src/utils/fx-status.ts +6 -1
  840. package/src/utils/inline-content-tokenizer.ts +22 -3
  841. package/src/utils/market-capitalization.ts +8 -0
  842. package/src/utils/one-shot.ts +73 -0
  843. package/src/utils/options.ts +37 -8
  844. package/src/utils/price-history.ts +99 -42
  845. package/src/utils/sec-eps-basis.ts +24 -11
  846. package/src/utils/sec.ts +61 -7
  847. package/src/utils/utc-time.ts +63 -4
  848. package/src/plugins/builtin/fx-matrix/freshness.ts +0 -65
  849. /package/src/plugins/{builtin/plugin-marketplace → marketplace}/activation.ts +0 -0
  850. /package/src/plugins/{builtin/plugin-marketplace → marketplace}/ids.ts +0 -0
  851. /package/src/plugins/{builtin/plugin-marketplace → marketplace}/packs.ts +0 -0
  852. /package/src/{plugins/builtin/cloud → tickers}/starter-symbols.ts +0 -0
@@ -23,11 +23,13 @@ import {
23
23
  } from "../../../components";
24
24
  import { loadingErrorFooterInfo } from "../../../components/data-table/table-pane";
25
25
  import { colors } from "../../../theme/colors";
26
+ import { t, tf } from "../../../i18n";
26
27
  import type { PaneProps } from "../../../types/plugin";
27
28
  import { Box, ScrollBox, Text, TextAttributes, useUiCapabilities, type ScrollBoxRenderable } from "../../../ui";
28
29
  import { useDialog, type PromptContext } from "../../../ui/dialog";
29
30
  import { isPlainKeyboardEvent } from "../../../utils/keyboard";
30
31
  import { formatRelativeAge } from "../../../utils/datetime-format";
32
+ import { displayWidth } from "../../../utils/format";
31
33
  import { requiredGloomberb } from "../../../utils/semver";
32
34
  import { VERSION } from "../../../version";
33
35
  import { getCurrentPluginTarget, runsExternalPlugins } from "../../current-target";
@@ -36,7 +38,7 @@ import { useAppSelector } from "../../../state/app/context";
36
38
  import { BUILTIN_EDITORIAL } from "../../builtin-editorial";
37
39
  import { usePluginAppActions, usePluginPaneState } from "../../runtime";
38
40
  import { DEBUG_LOG_TEMPLATE_ID } from "../debug/template";
39
- import { loadRegistry, registryPluginUrl } from "./feed";
41
+ import { loadRegistry, registryPluginUrl } from "../../marketplace/feed";
40
42
  import { highlightedCodes, pluginFunctions, proFunctionCount, type PluginFunction } from "../../plugin-functions";
41
43
  import {
42
44
  matchingPack,
@@ -46,7 +48,7 @@ import {
46
48
  STARTER_PACKS,
47
49
  type PackChange,
48
50
  type StarterPack,
49
- } from "./packs";
51
+ } from "../../marketplace/packs";
50
52
  import {
51
53
  buildRows,
52
54
  collectCategories,
@@ -67,11 +69,11 @@ import {
67
69
  type MarketplaceRow,
68
70
  type MarketplaceStatusKind,
69
71
  type RegistryPlugin,
70
- } from "./model";
71
- import { activateInstall, activateInstalledPlugin } from "./activation";
72
- import { getMarketplaceHost, getPluginManager, type MarketplaceHost } from "./store";
72
+ } from "../../marketplace/model";
73
+ import { activateInstall, activateInstalledPlugin } from "../../marketplace/activation";
74
+ import { getMarketplaceHost, getPluginManager, type MarketplaceHost } from "../../marketplace/store";
73
75
 
74
- import { PLUGIN_MARKETPLACE_PANE_ID } from "./ids";
76
+ import { PLUGIN_MARKETPLACE_PANE_ID } from "../../marketplace/ids";
75
77
 
76
78
  type Column = DataTableColumn & { id: "name" | "tagline" | "panes" | "functions" | "pro" | "status" };
77
79
 
@@ -158,12 +160,6 @@ function rowKey(row: MarketplaceRow): string {
158
160
 
159
161
  const isEntryRow = (row: MarketplaceRow) => row.type === "entry";
160
162
 
161
- function renderRowSectionHeader(row: MarketplaceRow) {
162
- return row.type === "header"
163
- ? { text: `${SECTION_LABELS[row.section]} (${row.count})` }
164
- : null;
165
- }
166
-
167
163
  function renderCell(
168
164
  row: MarketplaceRow,
169
165
  column: Column,
@@ -356,31 +352,38 @@ function BuiltinDetail({ entry, width, facts, scrollRef }: {
356
352
  );
357
353
  }
358
354
 
359
- /** The strip's labels; the full names are in the menu, the confirmation and the toast. */
360
- const PACK_SHORT_LABELS: Record<string, string> = {
361
- everything: "Everything",
362
- "equity-research": "Equity",
363
- "options-desk": "Options",
364
- "macro-rates": "Macro",
365
- "credit-bonds": "Credit",
366
- "alt-data-quant": "Alt data",
367
- };
368
- /** The strip's value when the plugins on match no pack. */
369
- const CUSTOM_PACK = "custom";
355
+ /**
356
+ * What the research heading says the plugins on are: the pack they match, or
357
+ * a custom set once someone switched one by hand.
358
+ */
359
+ function packStateLabel(pack: StarterPack | null): string {
360
+ return pack ? tf("{name} pack", { name: pack.name }) : t("Custom set");
361
+ }
362
+
363
+ /** What choosing a pack would switch from here, for its row in the chooser. */
364
+ function packChangeSummary(change: PackChange): string {
365
+ if (change.turnOff.length === 0 && change.turnOn.length === 0) return t("current");
366
+ return [
367
+ ...(change.turnOn.length > 0 ? [tf("{count} on", { count: change.turnOn.length })] : []),
368
+ ...(change.turnOff.length > 0 ? [tf("{count} off", { count: change.turnOff.length })] : []),
369
+ ].join(", ");
370
+ }
370
371
 
371
- /** One line per kind of change, with the plugins it names. */
372
- function PackChangeBody({ change, name, width }: { change: PackChange; name: (id: string) => string; width: number }) {
372
+ /** One line per kind of change, with the plugins it names; as wide as the dialog it sits in. */
373
+ function PackChangeBody({ change, name }: { change: PackChange; name: (id: string) => string }) {
373
374
  const lines = [
374
- { label: "Turn off", ids: change.turnOff },
375
- { label: "Turn on", ids: change.turnOn },
376
- { label: "Keep", ids: change.keep },
377
- ].filter((line) => line.ids.length > 0);
375
+ { label: t("Turn off"), ids: change.turnOff },
376
+ { label: t("Turn on"), ids: change.turnOn },
377
+ { label: t("Keep"), ids: change.keep },
378
+ ].filter((line) => line.ids.length > 0).map((line) => ({ ...line, heading: `${line.label} ${line.ids.length}` }));
379
+ // Wide enough for the longest heading in any language, plus a gap.
380
+ const headingWidth = Math.max(12, ...lines.map((line) => displayWidth(line.heading) + 2));
378
381
  return (
379
- <Box flexDirection="column" width={width} gap={1}>
382
+ <Box flexDirection="column" width="100%" gap={1}>
380
383
  {lines.map((line) => (
381
- <Box key={line.label} flexDirection="row" width={width}>
382
- <Box width={12} flexShrink={0}>
383
- <Text fg={colors.textBright} attributes={TextAttributes.BOLD}>{`${line.label} ${line.ids.length}`}</Text>
384
+ <Box key={line.label} flexDirection="row" width="100%">
385
+ <Box width={headingWidth} flexShrink={0}>
386
+ <Text fg={colors.textBright} attributes={TextAttributes.BOLD}>{line.heading}</Text>
384
387
  </Box>
385
388
  <Box flexGrow={1} flexShrink={1} minWidth={0}>
386
389
  <Text fg={colors.text} wrapText>{line.ids.map(name).join(", ")}</Text>
@@ -388,7 +391,7 @@ function PackChangeBody({ change, name, width }: { change: PackChange; name: (id
388
391
  </Box>
389
392
  ))}
390
393
  {change.turnOff.length > 0 ? (
391
- <Text fg={colors.textDim} wrapText>Panes are hidden, not closed. Undo brings them back.</Text>
394
+ <Text fg={colors.textDim} wrapText>{t("Panes are hidden, not closed. Undo brings them back.")}</Text>
392
395
  ) : null}
393
396
  </Box>
394
397
  );
@@ -678,13 +681,13 @@ export function PluginMarketplacePane({ focused, width, height }: PaneProps) {
678
681
  const change = packChange(previous, pack);
679
682
  const toggles = packToggles(change);
680
683
  if (Object.keys(toggles).length === 0) {
681
- notify({ body: `${pack.name} is already what you have on.`, type: "info" });
684
+ notify({ body: tf("{name} is already what you have on.", { name: pack.name }), type: "info" });
682
685
  return;
683
686
  }
684
687
  const confirmed = await confirmDialog(dialog, {
685
- title: `Switch to ${pack.name}?`,
686
- body: <PackChangeBody change={change} name={pluginName} width={confirmWidth} />,
687
- confirmLabel: "Switch",
688
+ title: tf("Apply {name}?", { name: pack.name }),
689
+ body: <PackChangeBody change={change} name={pluginName} />,
690
+ confirmLabel: "Apply",
688
691
  confirmVariant: "primary",
689
692
  width: confirmWidth,
690
693
  });
@@ -692,16 +695,16 @@ export function PluginMarketplacePane({ focused, width, height }: PaneProps) {
692
695
  host.setPluginsEnabled(toggles);
693
696
  bump();
694
697
  const parts = [
695
- ...(change.turnOff.length > 0 ? [`${change.turnOff.length} off`] : []),
696
- ...(change.turnOn.length > 0 ? [`${change.turnOn.length} back on`] : []),
698
+ ...(change.turnOff.length > 0 ? [tf("{count} off", { count: change.turnOff.length })] : []),
699
+ ...(change.turnOn.length > 0 ? [tf("{count} back on", { count: change.turnOn.length })] : []),
697
700
  ];
698
701
  notify({
699
- body: `${pack.name}: ${parts.join(", ")}.`,
702
+ body: tf("{name} applied: {changes}.", { name: pack.name, changes: parts.join(", ") }),
700
703
  type: "success",
701
704
  // Long enough to reach for Undo after looking at the list.
702
705
  duration: 12_000,
703
706
  action: {
704
- label: "Undo",
707
+ label: t("Undo"),
705
708
  onClick: () => {
706
709
  host.setPluginsEnabled(restoreToggles(previous));
707
710
  bump();
@@ -710,21 +713,44 @@ export function PluginMarketplacePane({ focused, width, height }: PaneProps) {
710
713
  });
711
714
  }, [bump, confirmWidth, dialog, disabledPlugins, host, notify, pluginName]);
712
715
 
716
+ /**
717
+ * The packs as templates to apply: each with its tagline and what it would
718
+ * switch from the plugins on now. Picking one goes to the confirmation that
719
+ * names those plugins.
720
+ */
713
721
  const choosePack = useCallback(async () => {
722
+ if (!host) return;
714
723
  const id = await dialog.prompt<string>({
715
724
  closeOnClickOutside: true,
716
725
  content: (context: PromptContext<string>) => (
717
726
  <ChoiceDialog
718
727
  {...context}
719
- title="Starter packs"
728
+ title="Apply a starter pack"
720
729
  selectedChoiceId={currentPack?.id}
721
- choices={STARTER_PACKS.map((pack) => ({ id: pack.id, label: pack.name, description: pack.tagline }))}
730
+ choices={STARTER_PACKS.map((pack) => ({
731
+ id: pack.id,
732
+ label: pack.name,
733
+ description: pack.tagline,
734
+ detail: packChangeSummary(packChange(disabledPlugins, pack)),
735
+ }))}
722
736
  />
723
737
  ),
724
738
  }).catch(() => null);
725
739
  const pack = STARTER_PACKS.find((candidate) => candidate.id === id);
726
740
  if (pack) await applyPack(pack);
727
- }, [applyPack, currentPack, dialog]);
741
+ }, [applyPack, currentPack, dialog, disabledPlugins, host]);
742
+
743
+ // The pack reaches exactly the research section, so its heading says which
744
+ // one the plugins on match and applies another.
745
+ const renderSectionHeader = useCallback((row: MarketplaceRow) => {
746
+ if (row.type !== "header") return null;
747
+ const text = `${SECTION_LABELS[row.section]} (${row.count})`;
748
+ if (row.section !== "research" || !host) return { text };
749
+ return {
750
+ text,
751
+ action: { label: packStateLabel(currentPack), title: t("Apply a starter pack"), onPress: () => { void choosePack(); } },
752
+ };
753
+ }, [choosePack, currentPack, host]);
728
754
 
729
755
  const setupSelected = useCallback(() => {
730
756
  if (!selected || !selected.installed || !selected.hasSetup || !selected.enabled) return;
@@ -826,7 +852,7 @@ export function PluginMarketplacePane({ focused, width, height }: PaneProps) {
826
852
  if (canOpen) hints.push({ id: "open-pane", key: "p", label: "ane", onPress: openSelected });
827
853
  if (canLog) hints.push({ id: "log", key: "d", label: "ebug log", onPress: openLog });
828
854
  if (canRemove) hints.push({ id: "remove", key: "x", label: " remove", onPress: () => { void removeSelected(); } });
829
- if (host) hints.push({ id: "packs", key: "a", label: " packs", title: "Starter packs", onPress: () => { void choosePack(); } });
855
+ if (host) hints.push({ id: "packs", key: "a", label: "pply pack", title: "Apply a starter pack", onPress: () => { void choosePack(); } });
830
856
  // A built-in has no repository; its page on gloom.sh shows it at work.
831
857
  const seeItUrl = selected?.bundled ? registryPluginUrl(selected.id) : null;
832
858
  if (seeItUrl) hints.push({ id: "see-it", key: "o", label: " see it", title: "See it on gloom.sh", onPress: () => openUrl(seeItUrl) });
@@ -845,10 +871,6 @@ export function PluginMarketplacePane({ focused, width, height }: PaneProps) {
845
871
  status: Math.min(14, Math.max(7, ...visible.map((entry) => statusOf(entry).text.length))),
846
872
  }), [factsFor, visible]);
847
873
  const columns = useMemo(() => buildColumns(width, fit), [fit, width]);
848
- const packOptions = useMemo(() => [
849
- ...STARTER_PACKS.map((pack) => ({ value: pack.id, label: pack.name, short: PACK_SHORT_LABELS[pack.id], description: pack.tagline })),
850
- ...(currentPack ? [] : [{ value: CUSTOM_PACK, label: "Custom", description: "Your own set of plugins.", disabled: true }]),
851
- ], [currentPack]);
852
874
  // The pick is saved with the pane, so keep it listed (and resettable) even
853
875
  // when the catalog no longer has plugins in it.
854
876
  const categoryOptions = useMemo(
@@ -899,21 +921,6 @@ export function PluginMarketplacePane({ focused, width, height }: PaneProps) {
899
921
  : null}
900
922
  detailTitle={selected?.name}
901
923
  rootBefore={(
902
- <Box flexDirection="column" flexShrink={0}>
903
- <QueryBar
904
- width={width}
905
- filters={[{
906
- id: "pack",
907
- label: "Starter pack",
908
- inline: true,
909
- value: currentPack?.id ?? CUSTOM_PACK,
910
- options: packOptions,
911
- onChange: (value: string) => {
912
- const pack = STARTER_PACKS.find((candidate) => candidate.id === value);
913
- if (pack) void applyPack(pack);
914
- },
915
- }]}
916
- />
917
924
  <QueryBar
918
925
  width={width}
919
926
  search={{
@@ -935,7 +942,6 @@ export function PluginMarketplacePane({ focused, width, height }: PaneProps) {
935
942
  { kind: "toggle" as const, id: "builtin", label: "Built in", value: showBuiltin, defaultValue: true, onChange: setShowBuiltin },
936
943
  ]}
937
944
  />
938
- </Box>
939
945
  )}
940
946
  selection={{
941
947
  kind: "id",
@@ -958,7 +964,7 @@ export function PluginMarketplacePane({ focused, width, height }: PaneProps) {
958
964
  getItemKey={rowKey}
959
965
  sortColumnId={null}
960
966
  sortDirection="asc"
961
- renderSectionHeader={renderRowSectionHeader}
967
+ renderSectionHeader={renderSectionHeader}
962
968
  renderCell={renderRow}
963
969
  emptyContent={<Box width="100%" paddingX={1} paddingY={1}>{emptyState}</Box>}
964
970
  emptyStateTitle={status === "error" ? "Plugin catalog unavailable." : query || category ? "No plugins match." : "Nothing installed yet."}
@@ -46,6 +46,7 @@ const HANDLED_MODULE_KEYS = [
46
46
  "panes",
47
47
  "paneTemplates",
48
48
  "capabilities",
49
+ "series",
49
50
  "slots",
50
51
  ] as const satisfies readonly (keyof PluginModule)[];
51
52
 
@@ -140,6 +141,7 @@ export function composeBuiltinPlugin(options: CompositePluginOptions): GloomPlug
140
141
  const panes = modules.flatMap((module) => module.panes ?? []);
141
142
  const paneTemplates = modules.flatMap((module) => module.paneTemplates ?? []);
142
143
  const capabilities = modules.flatMap((module) => module.capabilities ?? []);
144
+ const series = modules.flatMap((module) => module.series ?? []);
143
145
  const slots = composeSlots(modules);
144
146
  let startedModules: PluginModule[] = [];
145
147
 
@@ -149,6 +151,7 @@ export function composeBuiltinPlugin(options: CompositePluginOptions): GloomPlug
149
151
  ...(panes.length > 0 ? { panes } : {}),
150
152
  ...(paneTemplates.length > 0 ? { paneTemplates } : {}),
151
153
  ...(capabilities.length > 0 ? { capabilities } : {}),
154
+ ...(series.length > 0 ? { series } : {}),
152
155
  ...(slots ? { slots } : {}),
153
156
 
154
157
  async setup(ctx: GloomPluginContext) {
@@ -1,7 +1,7 @@
1
1
  import type { BrokerAccount } from "../../../types/trading";
2
2
  import { isTimestampStaleForExchangeSession } from "../../../market-data/market/freshness";
3
3
  import type { PortfolioSummaryTotals } from "./metrics";
4
- import { portfolioPnlPercent } from "./position-metrics";
4
+ import { portfolioPnlPercent } from "../../../portfolio/position-metrics";
5
5
  import { isFiniteNumber } from "../../../utils/guards";
6
6
 
7
7
  export interface PortfolioAccountMetrics {
@@ -211,9 +211,10 @@ export function formatAllocationDrift(value: number | null | undefined): string
211
211
  }
212
212
 
213
213
  /**
214
- * Units to trade, signed. A holding kept in whole units trades in whole units,
215
- * rounded to the nearest; fractional holdings and coins keep four decimals
216
- * (eight for coins).
214
+ * Units to trade, signed, at display precision: a holding kept in whole units
215
+ * trades in whole units, rounded to the nearest; a fractional holding to at
216
+ * most two decimals and a coin to at most four, trailing zeros dropped. JSON,
217
+ * CSV and the pane's cell value keep the full-precision figure.
217
218
  */
218
219
  export function formatTradeUnits(
219
220
  value: number | null | undefined,
@@ -222,7 +223,7 @@ export function formatTradeUnits(
222
223
  if (!finite(value)) return "—";
223
224
  const kind = resolveAssetDisplayKind({ assetCategory });
224
225
  const whole = kind !== "crypto" && kind !== "cash" && Number.isInteger(units);
225
- const decimals = whole ? 0 : kind === "crypto" ? 8 : 4;
226
+ const decimals = whole ? 0 : kind === "crypto" ? 4 : 2;
226
227
  const rounded = Number(value.toFixed(decimals));
227
228
  if (rounded === 0) return "0";
228
229
  const body = new Intl.NumberFormat("en-US", { maximumFractionDigits: decimals }).format(Math.abs(rounded));
@@ -20,8 +20,13 @@ const FX_COLUMN_IDS = new Set([
20
20
  ]);
21
21
  /** Columns that divide by the portfolio's total. */
22
22
  const ALLOCATION_COLUMN_IDS = new Set(["weight", "drift", "trade", "trade_value"]);
23
+ /** Columns read at the price the pane values at: the latest print or the regular close. */
24
+ const VALUATION_COLUMN_IDS = new Set([
25
+ "mkt_value", "weight", "drift", "trade", "trade_value", "day_pnl", "pnl", "pnl_pct", "as_of",
26
+ ]);
23
27
  const SUPPLEMENTAL_COLUMN_IDS = new Set(["target", "target_pct", "rating", "ex_div", "next_earn"]);
24
- const DAY_CLOCK_COLUMN_IDS = new Set(["held", "ex_div", "next_earn"]);
28
+ const DAY_CLOCK_COLUMN_IDS = new Set(["held", "ex_div", "next_earn", "as_of"]);
29
+ export const PERPETUAL_COLUMN_IDS: ReadonlySet<string> = new Set(["perp_premium", "perp_funding"]);
25
30
 
26
31
  const exchangeRateVersions = new WeakMap<ReadonlyMap<string, number>, string>();
27
32
 
@@ -53,8 +58,10 @@ export function columnContextVersion(columnId: string, ctx: ColumnContext): stri
53
58
  let version = `${ctx.activeTab ?? ""}|${ctx.baseCurrency}`;
54
59
  if (FX_COLUMN_IDS.has(columnId)) version += `|${exchangeRatesVersion(ctx.exchangeRates)}`;
55
60
  if (ALLOCATION_COLUMN_IDS.has(columnId)) version += `|${ctx.portfolioTotalMarketValue ?? 0}`;
61
+ if (VALUATION_COLUMN_IDS.has(columnId)) version += `|${ctx.valuationBasis ?? "latest-print"}`;
56
62
  if (ALLOCATION_COLUMN_IDS.has(columnId) || columnId === "target_weight") version += `|${targetsVersion(ctx.portfolioTargets)}`;
57
63
  if (SUPPLEMENTAL_COLUMN_IDS.has(columnId)) version += `|${ctx.supplementalVersion ?? 0}`;
64
+ if (PERPETUAL_COLUMN_IDS.has(columnId)) version += `|${ctx.perpetualsVersion ?? 0}`;
58
65
  if (columnId === "latency") version += `|${ctx.now}`;
59
66
  if (DAY_CLOCK_COLUMN_IDS.has(columnId)) version += `|${Math.floor(ctx.now / DAY_MS)}`;
60
67
  return version;
@@ -0,0 +1,161 @@
1
+ import type { CliCommandContext } from "../../../../types/plugin";
2
+ import type { TickerRecord } from "../../../../types/ticker";
3
+ import { loadSavedListing, parseListingArg } from "../../../../cli/listing-arg";
4
+ import { StagedTickerRepository } from "../../../../cli/staged-tickers";
5
+ import { splitSymbolArgs, symbolInputKey } from "../../../../cli/symbol-args";
6
+ import { readSymbolList, SymbolListError } from "../../../../cli/symbol-list";
7
+ import { cliStyles } from "../../../../utils/cli-output";
8
+ import {
9
+ addSymbols,
10
+ failedRow,
11
+ listingRow,
12
+ NO_MATCH,
13
+ reason,
14
+ settled,
15
+ summarizeSymbolRows,
16
+ type BulkSymbolsOptions,
17
+ type SymbolRow,
18
+ type SymbolStatus,
19
+ type Verb,
20
+ } from "../../../../cli/symbol-rows";
21
+
22
+ export { addSymbols };
23
+
24
+ /** The `--file` option of add and remove. */
25
+ export const FILE_OPTION = {
26
+ flags: "--file <path>",
27
+ description: "add, remove: read the symbols from a CSV or text file (- reads standard input)",
28
+ };
29
+
30
+ /** The help section on giving add and remove several symbols. */
31
+ export const SYMBOL_LIST_HELP = {
32
+ title: "Several symbols",
33
+ lines: [
34
+ "add and remove take any number of symbols split by spaces, commas or newlines, a --file, or piped input (or -). A CSV is read from its Symbol, Ticker or Code column, else its first. Quote a list name with spaces.",
35
+ "Each symbol gets a line, then a summary. Exit status 0 when at least one symbol was added (or removed) or already was, 1 when none resolved or the usage is wrong.",
36
+ ],
37
+ };
38
+
39
+ /** A row's line, and under it the coin hint when a bare coin ticker was read as something else. */
40
+ function rowLines(row: SymbolRow, verb: Verb): string {
41
+ const line = rowLine(row, verb);
42
+ return row.hint ? `${line}\n ${cliStyles.warning(row.hint)}` : line;
43
+ }
44
+
45
+ function rowLine(row: SymbolRow, verb: Verb): string {
46
+ const typed = symbolInputKey(row.input);
47
+ const label = row.listing ? (row.name ? `${row.listing} (${row.name})` : row.listing) : typed;
48
+ // A listing that stopped trading is still added, and says so.
49
+ const aside = row.message && row.listing ? cliStyles.muted(` (${reason(row.message, label)})`) : "";
50
+ switch (row.status) {
51
+ case "added": return `${cliStyles.success(`Added ${label}`)}${aside}`;
52
+ case "already_listed": return `${cliStyles.warning(`Already in the list: ${label}`)}${aside}`;
53
+ case "removed": return cliStyles.success(`Removed ${label}`);
54
+ case "not_listed": return cliStyles.warning(`Not in the list: ${label}`);
55
+ case "not_found": return cliStyles.danger(`Not found: ${typed}${row.message && !NO_MATCH.test(row.message) ? ` (${reason(row.message, typed)})` : ""}`);
56
+ case "failed": return cliStyles.danger(`Not ${verb === "add" ? "added" : "removed"}: ${typed} (${reason(row.message ?? "", typed)})`);
57
+ }
58
+ }
59
+
60
+ interface CollectionRef {
61
+ kind: "watchlist" | "portfolio";
62
+ name: string;
63
+ }
64
+
65
+ /**
66
+ * One line per symbol and the summary under them; `--json` and `--csv` give
67
+ * the rows, with the summary in the JSON metadata and on standard error beside
68
+ * CSV. The command exits non-zero when no symbol ended up as asked.
69
+ */
70
+ export function printSymbolRows(
71
+ ctx: CliCommandContext,
72
+ rows: SymbolRow[],
73
+ { verb, collection, repeated }: { verb: Verb; collection: CollectionRef; repeated: number },
74
+ ): void {
75
+ const summary = `${collection.kind === "watchlist" ? "Watchlist" : "Portfolio"} "${collection.name}": ${summarizeSymbolRows(rows, verb, repeated)}`;
76
+ const count = (status: SymbolStatus) => rows.filter((row) => row.status === status).length;
77
+ const counts = verb === "add"
78
+ ? { added: count("added"), alreadyListed: count("already_listed"), notFound: count("not_found"), notAdded: count("failed") }
79
+ : { removed: count("removed"), notListed: count("not_listed"), notFound: count("not_found"), notRemoved: count("failed") };
80
+ ctx.printResult({
81
+ data: rows,
82
+ metadata: { [collection.kind]: collection.name, ...counts, repeated, summary },
83
+ }, {
84
+ text: () => [...rows.map((row) => rowLines(row, verb)), "", summary].join("\n"),
85
+ });
86
+ const { format, quiet } = ctx.cliOptions;
87
+ if ((format === "csv" || format === "ndjson") && !quiet) console.error(summary);
88
+ if (!rows.some((row) => settled(row, verb))) process.exitCode = 1;
89
+ }
90
+
91
+ /** A line on standard error while a long add waits to look symbols up again, so it never looks stuck. */
92
+ export function retryNotice(ctx: CliCommandContext): (count: number, waitMs: number) => void {
93
+ return (count, waitMs) => {
94
+ if (ctx.cliOptions.quiet) return;
95
+ console.error(cliStyles.muted(`Gloom Cloud refused some requests; looking ${count} symbol${count === 1 ? "" : "s"} up again in ${Math.round(waitMs / 1000)} s.`));
96
+ };
97
+ }
98
+
99
+ /** The symbols an add or remove was given, failing the command when there are none or the file cannot be read. */
100
+ export async function requireSymbolList(
101
+ ctx: CliCommandContext,
102
+ args: readonly string[],
103
+ file: string | undefined,
104
+ usage: string,
105
+ ): Promise<{ symbols: string[]; repeated: number; single: string | null }> {
106
+ try {
107
+ const list = await readSymbolList({ args, file });
108
+ if (list.symbols.length === 0) ctx.fail(usage);
109
+ // One symbol typed alone keeps the single-symbol output and errors.
110
+ const typed = splitSymbolArgs(args);
111
+ const single = file == null && !args.includes("-") && typed.length === 1 ? typed[0]! : null;
112
+ return { ...list, single };
113
+ } catch (error) {
114
+ if (error instanceof SymbolListError) ctx.fail(error.message, usage);
115
+ throw error;
116
+ }
117
+ }
118
+
119
+ /**
120
+ * Removes each symbol's saved listing from a collection. A symbol names its
121
+ * listing as the single-symbol remove reads it (SAN:EPA, or `--exchange` for
122
+ * those without one); one that is not saved is not found. Every change is
123
+ * written once, at the end.
124
+ */
125
+ export async function removeSymbols({
126
+ symbols,
127
+ exchange,
128
+ store,
129
+ reject,
130
+ remove,
131
+ }: BulkSymbolsOptions & {
132
+ reject?: (input: string) => Error | null;
133
+ remove: (ticker: TickerRecord) => { changed: boolean; ticker: TickerRecord; extra?: Record<string, unknown> };
134
+ }): Promise<SymbolRow[]> {
135
+ const staged = new StagedTickerRepository(store);
136
+ const rows: SymbolRow[] = [];
137
+ for (const input of symbols) {
138
+ const refusal = reject?.(input);
139
+ if (refusal) {
140
+ rows.push(failedRow(input, refusal));
141
+ continue;
142
+ }
143
+ let listing;
144
+ try {
145
+ listing = parseListingArg(input, exchange, { ownExchangeWins: true });
146
+ } catch (error) {
147
+ rows.push(failedRow(input, error instanceof Error ? error : new Error(String(error))));
148
+ continue;
149
+ }
150
+ const ticker = listing.symbol ? await loadSavedListing(staged, listing) : null;
151
+ if (!ticker) {
152
+ rows.push(failedRow(input, new Error(`Ticker "${listing.key}" was not found in your local data.`), "not_found"));
153
+ continue;
154
+ }
155
+ const result = remove(ticker);
156
+ if (result.changed) await staged.saveTicker(result.ticker);
157
+ rows.push(listingRow(input, result.changed ? "removed" : "not_listed", result.ticker, { extra: result.extra }));
158
+ }
159
+ await staged.commit();
160
+ return rows;
161
+ }
@@ -0,0 +1,109 @@
1
+ import type { HeadlessPaneRow } from "../../../../types/plugin";
2
+ import type { PortfolioImportSource } from "../../../../types/ticker";
3
+
4
+ /**
5
+ * A 13F line ranked by reported value, with why it cannot be a portfolio
6
+ * position when it cannot. Read from the rows `fn 13F <manager>` reports, so
7
+ * the import goes through the 13F function rather than the 13F plugin's code.
8
+ */
9
+ export interface ThirteenFImportLine {
10
+ ticker: string;
11
+ issuer: string;
12
+ cusip: string;
13
+ /** Reported value, USD. */
14
+ value: number;
15
+ shares: number;
16
+ /** Null for a line that can be imported. */
17
+ skip: string | null;
18
+ }
19
+
20
+ export interface ThirteenFImportPosition {
21
+ ticker: string;
22
+ issuer: string;
23
+ /** Share of the imported lines' reported value. */
24
+ weight: number;
25
+ /** Share of the whole filing's reported value. */
26
+ filingWeight: number | null;
27
+ /** Reported shares scaled to the notional. */
28
+ shares: number;
29
+ /** Reported value per share: the quarter-end price the filing implies. */
30
+ avgCost: number;
31
+ }
32
+
33
+ const text = (value: unknown) => (typeof value === "string" ? value : "");
34
+
35
+ /** Title-of-class words for lines that are shares but not common stock ("6.375 PREF SER A", "*W EXP 06/30/202"). */
36
+ const NOT_COMMON: Array<[RegExp, string]> = [
37
+ [/\b(?:PFD|PREF|PREFERRED)\b/i, "preferred stock"],
38
+ [/\*W\b|\b(?:WTS?|WARRANTS?)\b/i, "warrant"],
39
+ [/\b(?:RTS?|RIGHTS?)\b/i, "right"],
40
+ [/\b(?:NOTES?|DBCV|DEBT|BONDS?)\b/i, "debt"],
41
+ ];
42
+ const amount = (value: unknown) => (typeof value === "number" && Number.isFinite(value) ? value : null);
43
+
44
+ /**
45
+ * The manager's current 13F lines, largest reported value first. Common-stock
46
+ * lines with a ticker can become positions; options, principal amounts,
47
+ * preferred stock, warrants, rights and debt, and lines whose CUSIP has no
48
+ * ticker carry the reason they cannot. Two CUSIPs that map to one ticker are
49
+ * one line.
50
+ */
51
+ export function rankThirteenFLines(rows: readonly HeadlessPaneRow[]): ThirteenFImportLine[] {
52
+ const lines = new Map<string, ThirteenFImportLine>();
53
+ for (const [index, row] of rows.entries()) {
54
+ const value = amount(row.value);
55
+ if (row.action === "exit" || value == null || value <= 0) continue;
56
+ const ticker = text(row.ticker);
57
+ const shares = amount(row.shares);
58
+ const putCall = text(row.putCall);
59
+ const notCommon = NOT_COMMON.find(([pattern]) => pattern.test(text(row.titleOfClass)))?.[1];
60
+ const skip = putCall ? `${putCall.toLowerCase()} option, not shares`
61
+ : text(row.shareType).toUpperCase() === "PRN" ? "principal amount, not shares"
62
+ : notCommon ? `${notCommon}, not common stock`
63
+ : !ticker ? `CUSIP ${text(row.cusip) || "unknown"} has no ticker`
64
+ : shares == null || shares <= 0 ? "no share count reported"
65
+ : null;
66
+ const key = skip ? `${index}|skip` : ticker.toUpperCase();
67
+ const line = lines.get(key);
68
+ if (line) {
69
+ line.value += value;
70
+ line.shares += shares ?? 0;
71
+ } else {
72
+ lines.set(key, { ticker, issuer: text(row.issuer), cusip: text(row.cusip), value, shares: shares ?? 0, skip });
73
+ }
74
+ }
75
+ return [...lines.values()].sort((left, right) => right.value - left.value);
76
+ }
77
+
78
+ /** Round to four decimals: a notional share count need not be whole, but it need not show float noise either. */
79
+ const roundShares = (value: number) => Math.round(value * 10_000) / 10_000;
80
+
81
+ /**
82
+ * Positions worth `notional` in total, weighted by reported value: each line's
83
+ * reported shares scaled by notional over the lines' total value, at the
84
+ * quarter-end price the filing implies.
85
+ */
86
+ export function notionalPositions(
87
+ lines: readonly Pick<ThirteenFImportLine, "ticker" | "issuer" | "value" | "shares">[],
88
+ notional: number,
89
+ filingValue: number | null,
90
+ ): ThirteenFImportPosition[] {
91
+ const total = lines.reduce((sum, line) => sum + line.value, 0);
92
+ if (!(total > 0) || !(notional > 0)) return [];
93
+ return lines.map((line) => ({
94
+ ticker: line.ticker,
95
+ issuer: line.issuer,
96
+ weight: line.value / total,
97
+ filingWeight: filingValue && filingValue > 0 ? line.value / filingValue : null,
98
+ shares: roundShares(line.shares * notional / total),
99
+ avgCost: line.value / line.shares,
100
+ }));
101
+ }
102
+
103
+ /** The filing a 13F holdings report covers, from its metadata, or null when it names no dated filing. */
104
+ export function importSource(metadata: Record<string, unknown> | undefined): PortfolioImportSource | null {
105
+ const cik = text(metadata?.cik), name = text(metadata?.fund);
106
+ const period = text(metadata?.latestPeriod), filed = text(metadata?.latestFiled);
107
+ if (!cik || !period || !filed) return null;
108
+ return { kind: "13f", cik, name: name || cik, period, filed };
109
+ }