gloomberb 0.18.3 → 0.18.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (886) hide show
  1. package/README.md +8 -8
  2. package/README.zh-CN.md +11 -11
  3. package/bin/{gloomberb → gloom} +3 -1
  4. package/package.json +6 -2
  5. package/src/account/checkout-handoff.tsx +225 -0
  6. package/src/account/device-signin-dialog.tsx +2 -2
  7. package/src/account/device-signin.ts +2 -2
  8. package/src/account/upgrade-dialog.tsx +1 -1
  9. package/src/api-client/askg.ts +2 -2
  10. package/src/api-client/auth.ts +2 -2
  11. package/src/api-client/central-bank-rates.ts +6 -0
  12. package/src/api-client/collections.ts +5 -1
  13. package/src/api-client/cot.ts +2 -0
  14. package/src/api-client/crypto-etf-flows.ts +37 -0
  15. package/src/api-client/crypto-markets.ts +60 -0
  16. package/src/api-client/data.ts +84 -5
  17. package/src/api-client/doe.ts +15 -0
  18. package/src/api-client/equity-screener.ts +28 -0
  19. package/src/api-client/exchange-announcements.ts +38 -0
  20. package/src/api-client/fund-facts.ts +39 -0
  21. package/src/api-client/futures-curve.ts +9 -1
  22. package/src/api-client/hiring.ts +301 -0
  23. package/src/api-client/index.ts +22 -5
  24. package/src/api-client/market-discovery.ts +14 -0
  25. package/src/api-client/members.ts +6 -0
  26. package/src/api-client/mna.ts +6 -0
  27. package/src/api-client/paths.ts +18 -1
  28. package/src/api-client/request.ts +21 -4
  29. package/src/api-client/short-side-publications.ts +37 -0
  30. package/src/api-client/socket.ts +64 -4
  31. package/src/api-client/swap-curve.ts +35 -0
  32. package/src/api-client/themes.ts +7 -1
  33. package/src/api-client/types.ts +90 -2
  34. package/src/app/pane-runtime/plugin-bindings.ts +9 -2
  35. package/src/app/runtime/desktop-deeplink.ts +5 -5
  36. package/src/app/runtime/plugin-bindings.ts +2 -2
  37. package/src/app/runtime/startup.ts +13 -0
  38. package/src/app/star-prompt/status-line.tsx +2 -2
  39. package/src/architecture/core-builtin-allowlist.json +5 -2
  40. package/src/architecture/ui-literals-allowlist.json +3 -3
  41. package/src/architecture/ui-tokens-allowlist.json +1 -1
  42. package/src/brokers/broker-portfolio-sync.ts +37 -0
  43. package/src/brokers/directory.ts +11 -0
  44. package/src/brokers/logos.ts +3 -1
  45. package/src/brokers/signed-in/adapter.ts +304 -26
  46. package/src/brokers/signed-in/client.ts +14 -2
  47. package/src/brokers/signed-in/connect.ts +10 -2
  48. package/src/brokers/sync-broker-instance.ts +9 -1
  49. package/src/capabilities/chart-series.ts +22 -6
  50. package/src/cli/bank-section.ts +1 -1
  51. package/src/cli/base-converter.ts +23 -14
  52. package/src/cli/central-bank-events.ts +1 -1
  53. package/src/cli/command-options.ts +59 -4
  54. package/src/cli/commands/api.ts +9 -6
  55. package/src/cli/commands/broker.ts +2 -2
  56. package/src/cli/commands/command-utils.ts +2 -2
  57. package/src/cli/commands/crypto-hints.ts +7 -20
  58. package/src/cli/commands/fred-series.ts +4 -2
  59. package/src/cli/commands/keybindings.ts +2 -2
  60. package/src/cli/commands/market.ts +1117 -264
  61. package/src/cli/commands/news-hints.ts +2 -2
  62. package/src/cli/commands/news-search.ts +59 -6
  63. package/src/cli/commands/options-leaps.ts +41 -26
  64. package/src/cli/commands/overview.ts +121 -48
  65. package/src/cli/commands/plugins.ts +9 -9
  66. package/src/cli/commands/remote.ts +13 -10
  67. package/src/cli/commands/search.ts +64 -44
  68. package/src/cli/commands/system.ts +27 -19
  69. package/src/cli/commands/themes.ts +1 -1
  70. package/src/cli/commands/ticker.ts +192 -47
  71. package/src/cli/context.ts +3 -2
  72. package/src/cli/desktop-pane-shot-view.ts +2 -2
  73. package/src/cli/desktop-pane-shot.ts +1 -1
  74. package/src/cli/earnings-calendar.ts +4 -4
  75. package/src/cli/entry.ts +18 -1
  76. package/src/cli/errors.ts +20 -2
  77. package/src/cli/exit-codes.ts +1 -1
  78. package/src/cli/export-source.ts +10 -4
  79. package/src/cli/freshness.ts +2 -8
  80. package/src/cli/fx-forward.ts +130 -0
  81. package/src/cli/fx-pair.ts +10 -9
  82. package/src/cli/glossary.ts +64 -20
  83. package/src/cli/help.ts +19 -13
  84. package/src/cli/history-export.ts +126 -0
  85. package/src/cli/history-rows.ts +196 -43
  86. package/src/cli/index-roots.ts +5 -45
  87. package/src/cli/index.ts +24 -18
  88. package/src/cli/known-gaps.ts +118 -25
  89. package/src/cli/listing-arg.ts +300 -41
  90. package/src/cli/name-entries.ts +30 -18
  91. package/src/cli/native-smoke.ts +2 -0
  92. package/src/cli/not-a-ticker.ts +19 -9
  93. package/src/cli/opentui-libc.ts +5 -0
  94. package/src/cli/options.ts +12 -0
  95. package/src/cli/pane-functions/capabilities.ts +75 -20
  96. package/src/cli/pane-functions/catalog.ts +24 -23
  97. package/src/cli/pane-functions/discovery.ts +1 -1
  98. package/src/cli/pane-functions/dom.ts +10 -7
  99. package/src/cli/pane-functions/financial-ratio-shot.ts +2 -2
  100. package/src/cli/pane-functions/freshness.ts +174 -23
  101. package/src/cli/pane-functions/function-help.ts +66 -27
  102. package/src/cli/pane-functions/headless.ts +24 -11
  103. package/src/cli/pane-functions/index.ts +18 -16
  104. package/src/cli/pane-functions/options.ts +22 -2
  105. package/src/cli/pane-functions/report-notices.ts +12 -4
  106. package/src/cli/pane-functions/report.ts +5 -5
  107. package/src/cli/pane-functions/resolver.ts +47 -10
  108. package/src/cli/pane-functions/screenshot-assessment.ts +322 -0
  109. package/src/cli/pane-functions/screenshot-bridge.ts +152 -0
  110. package/src/cli/pane-functions/screenshot-chart-evidence.ts +396 -0
  111. package/src/cli/pane-functions/screenshot-data-evidence.ts +383 -0
  112. package/src/cli/pane-functions/screenshot-evidence.ts +1 -1
  113. package/src/cli/pane-functions/screenshot-payload.ts +453 -0
  114. package/src/cli/pane-functions/screenshot-render.ts +316 -0
  115. package/src/cli/pane-functions/screenshot-types.ts +162 -0
  116. package/src/cli/pane-functions/shot-options.ts +8 -3
  117. package/src/cli/peso-dollar-rates.ts +79 -0
  118. package/src/cli/quote-answer.ts +38 -3
  119. package/src/cli/report-tables.ts +61 -16
  120. package/src/cli/restore-plugins.ts +29 -14
  121. package/src/cli/result.ts +111 -22
  122. package/src/cli/series-search.ts +5 -5
  123. package/src/cli/statement-filings.ts +19 -0
  124. package/src/cli/suffixed-listing-rows.ts +49 -0
  125. package/src/cli/symbol-args.ts +50 -15
  126. package/src/cli/symbol-cells.ts +120 -0
  127. package/src/cli/symbol-list.ts +198 -68
  128. package/src/cli/symbol-rows.ts +131 -25
  129. package/src/cli/ticker-resolution.ts +108 -11
  130. package/src/cli/treasury-yields.ts +5 -5
  131. package/src/cli/types.ts +2 -0
  132. package/src/cli/uncovered-instrument.ts +3 -3
  133. package/src/cli/unknown-command.ts +6 -6
  134. package/src/components/chart/composite/chart-layout.ts +131 -0
  135. package/src/components/chart/composite/composite-chart.tsx +373 -16
  136. package/src/components/chart/composite/interactions.ts +7 -2
  137. package/src/components/chart/composite/legend.tsx +75 -3
  138. package/src/components/chart/composite/levels.ts +5 -0
  139. package/src/components/chart/composite/panel-gestures.ts +41 -0
  140. package/src/components/chart/composite/panel-labels.ts +2 -1
  141. package/src/components/chart/composite/panel-surface.tsx +305 -11
  142. package/src/components/chart/composite/price-axis-labels.tsx +27 -3
  143. package/src/components/chart/composite/rasterizer.ts +44 -19
  144. package/src/components/chart/composite/scene.ts +16 -4
  145. package/src/components/chart/composite/text-renderer.ts +48 -21
  146. package/src/components/chart/composite/toolbar.tsx +52 -5
  147. package/src/components/chart/composite/types.ts +13 -0
  148. package/src/components/chart/composite/use-composite-chart-keyboard.ts +120 -13
  149. package/src/components/chart/composite/use-composite-value-scales.ts +44 -0
  150. package/src/components/chart/composite/use-composite-viewport.ts +12 -3
  151. package/src/components/chart/composite/value-scale.ts +149 -0
  152. package/src/components/chart/composite/volume-profile-paint.ts +6 -3
  153. package/src/components/chart/core/pointer.ts +2 -0
  154. package/src/components/chart-table/index.ts +2 -0
  155. package/src/components/chart-table/read.tsx +74 -0
  156. package/src/components/command-bar/commands/collection-list.ts +41 -19
  157. package/src/components/command-bar/commands/collection.ts +9 -3
  158. package/src/components/command-bar/commands/direct/index.ts +1 -1
  159. package/src/components/command-bar/commands/direct/runtime.ts +3 -2
  160. package/src/components/command-bar/pane-templates/items.ts +59 -6
  161. package/src/components/command-bar/pane-templates/workflow.ts +10 -1
  162. package/src/components/command-bar/routes/root/plugin-install.ts +1 -1
  163. package/src/components/command-bar/routes/root/provider-search.ts +42 -11
  164. package/src/components/command-bar/routes/root/results.ts +18 -4
  165. package/src/components/command-bar/routes/root/runtime.ts +15 -3
  166. package/src/components/command-bar/routes/root/search-providers.ts +25 -2
  167. package/src/components/command-bar/routes/root/selection.ts +6 -1
  168. package/src/components/command-bar/routes/root/shortcut-feedback.ts +4 -1
  169. package/src/components/command-bar/routes/root/shortcuts.ts +30 -3
  170. package/src/components/command-bar/routes/ticker-search/results.ts +73 -4
  171. package/src/components/command-bar/selection-runtime.ts +50 -10
  172. package/src/components/command-bar/surface/index.tsx +24 -2
  173. package/src/components/command-bar/view-model.ts +7 -0
  174. package/src/components/command-bar/workflow/broker.ts +2 -2
  175. package/src/components/command-bar/workflow/collection-actions.ts +46 -7
  176. package/src/components/command-bar/workflow/collection-ticker.ts +32 -4
  177. package/src/components/command-bar/workflow/fields.ts +8 -2
  178. package/src/components/command-bar/workflow/ops.ts +18 -4
  179. package/src/components/command-bar/workflow/portfolio-position.ts +53 -4
  180. package/src/components/command-bar/workflow/submit.ts +3 -2
  181. package/src/components/command-bar/workflow/tickers.ts +5 -1
  182. package/src/components/company-logo.tsx +39 -0
  183. package/src/components/data-table/sections.ts +4 -2
  184. package/src/components/form-modal/confirm.tsx +2 -1
  185. package/src/components/form-modal/request.ts +5 -0
  186. package/src/components/form-modal/routes.ts +4 -1
  187. package/src/components/index.ts +12 -6
  188. package/src/components/layout/header.tsx +7 -6
  189. package/src/components/layout/market-summary.ts +9 -6
  190. package/src/components/layout/pane/capture-status.ts +1 -1
  191. package/src/components/layout/pane/footer/model.ts +11 -5
  192. package/src/components/layout/shell/chrome.ts +19 -6
  193. package/src/components/layout/shell/index.tsx +2 -1
  194. package/src/components/layout/shell/pane/layers.tsx +19 -1
  195. package/src/components/layout/status-bar.tsx +2 -2
  196. package/src/components/market-board/index.tsx +11 -3
  197. package/src/components/onboarding/onboarding-wizard.tsx +1 -0
  198. package/src/components/onboarding/portfolio-step/broker-setup-panel.tsx +2 -2
  199. package/src/components/onboarding/wizard-broker-sync.ts +4 -1
  200. package/src/components/pane-settings-dialog/desktop.tsx +20 -7
  201. package/src/components/pane-settings-dialog/tui.tsx +17 -9
  202. package/src/components/pane-settings-dialog/value.ts +8 -1
  203. package/src/components/pane-settings-dialog.tsx +44 -13
  204. package/src/components/sign-in-code-panel.tsx +27 -19
  205. package/src/components/ui/column-grid.tsx +48 -4
  206. package/src/components/ui/country-flag-art.tsx +180 -0
  207. package/src/components/ui/country-flag.tsx +118 -12
  208. package/src/components/ui/data-table/opentui/index.tsx +61 -2
  209. package/src/components/ui/data-table/opentui/model.ts +109 -2
  210. package/src/components/ui/data-table/types.ts +1 -1
  211. package/src/components/ui/display.tsx +5 -1
  212. package/src/components/ui/index.ts +3 -1
  213. package/src/components/ui/logo-mark.tsx +11 -2
  214. package/src/components/ui/query-bar.tsx +1 -1
  215. package/src/components/ui/row-notes.ts +79 -0
  216. package/src/core/state/app/layout.ts +4 -4
  217. package/src/data/cached-query.ts +8 -1
  218. package/src/data/config/chart-settings.ts +3 -3
  219. package/src/data/config/home.ts +10 -2
  220. package/src/data/config/layout.ts +4 -1
  221. package/src/data/config/store/node.ts +4 -0
  222. package/src/data/config/store/normalize.ts +13 -3
  223. package/src/data/config/store/portfolio-as-of-column.ts +2 -2
  224. package/src/data/json-storage.ts +2 -0
  225. package/src/data/saved-copies.ts +84 -0
  226. package/src/docs/snapshot.json +65 -32
  227. package/src/i18n/es.ts +29 -12
  228. package/src/i18n/ja.ts +29 -12
  229. package/src/i18n/ko.ts +29 -12
  230. package/src/i18n/zh-cn.ts +29 -12
  231. package/src/i18n/zh-tw.ts +29 -12
  232. package/src/layout/desks.ts +1 -1
  233. package/src/layout/launch-layout.ts +1 -1
  234. package/src/layout/pane-manager/floating-actions.ts +5 -3
  235. package/src/layout/pane-manager/floating.ts +43 -1
  236. package/src/layout/pane-manager/index.ts +2 -0
  237. package/src/layout/selected-ticker.ts +74 -0
  238. package/src/market-data/depositary-pair.ts +251 -0
  239. package/src/market-data/futures-board.ts +1 -1
  240. package/src/market-data/futures-contract.ts +124 -40
  241. package/src/market-data/fx-closes.ts +17 -2
  242. package/src/market-data/hooks.tsx +19 -11
  243. package/src/market-data/market/change-basis.ts +49 -7
  244. package/src/market-data/market/freshness.ts +34 -5
  245. package/src/market-data/market/period-return.ts +163 -0
  246. package/src/market-data/market/trading-sessions.ts +13 -0
  247. package/src/market-data/market/year-to-date.ts +8 -13
  248. package/src/market-data/performance.ts +20 -14
  249. package/src/market-data/perpetual-premium.ts +32 -0
  250. package/src/market-data/published-apac-sessions.ts +2 -1
  251. package/src/market-data/published-futures-sessions.ts +69 -0
  252. package/src/market-data/quotes/contributions.ts +5 -1
  253. package/src/market-data/quotes/freshness.ts +42 -0
  254. package/src/market-data/quotes/intraday-bar.ts +37 -0
  255. package/src/market-data/quotes/regular-session-valuation.ts +13 -8
  256. package/src/market-data/quotes/resolution.ts +4 -2
  257. package/src/market-data/tax-equivalent.ts +1 -1
  258. package/src/market-data/ticker-price-returns.ts +3 -1
  259. package/src/news/aggregator.ts +5 -1
  260. package/src/news/news-model.ts +4 -0
  261. package/src/news/types.ts +11 -0
  262. package/src/notifications/app-notifier.ts +1 -1
  263. package/src/plugins/auto-update.ts +2 -2
  264. package/src/plugins/builtin/account-management/index.tsx +1 -0
  265. package/src/plugins/builtin/account-management/pane.tsx +9 -8
  266. package/src/plugins/builtin/alerts/alert-engine.ts +29 -19
  267. package/src/plugins/builtin/alerts/calendar-events.ts +378 -0
  268. package/src/plugins/builtin/alerts/cli.ts +485 -76
  269. package/src/plugins/builtin/alerts/command.ts +5 -10
  270. package/src/plugins/builtin/alerts/event-rows.ts +9 -5
  271. package/src/plugins/builtin/alerts/events-pane.tsx +71 -56
  272. package/src/plugins/builtin/alerts/events.ts +107 -5
  273. package/src/plugins/builtin/alerts/fired-log.ts +78 -0
  274. package/src/plugins/builtin/alerts/format.ts +2 -1
  275. package/src/plugins/builtin/alerts/headless.ts +100 -39
  276. package/src/plugins/builtin/alerts/history-pane.tsx +105 -62
  277. package/src/plugins/builtin/alerts/history-rows.ts +89 -0
  278. package/src/plugins/builtin/alerts/index.tsx +45 -18
  279. package/src/plugins/builtin/alerts/iv-level.ts +365 -0
  280. package/src/plugins/builtin/alerts/levels.ts +3 -3
  281. package/src/plugins/builtin/alerts/pane.tsx +97 -29
  282. package/src/plugins/builtin/alerts/price.ts +35 -0
  283. package/src/plugins/builtin/alerts/quotes.ts +24 -0
  284. package/src/plugins/builtin/alerts/research-builder.ts +84 -11
  285. package/src/plugins/builtin/alerts/research-rules.ts +76 -3
  286. package/src/plugins/builtin/alerts/scheduled-check.ts +206 -32
  287. package/src/plugins/builtin/alerts/scheduled-sources.ts +26 -3
  288. package/src/plugins/builtin/alerts/scheduled.ts +188 -29
  289. package/src/plugins/builtin/alerts/storage.ts +13 -10
  290. package/src/plugins/builtin/alerts/targets.ts +12 -3
  291. package/src/plugins/builtin/analytics/index.tsx +8 -2
  292. package/src/plugins/builtin/analytics/metrics.ts +1 -1
  293. package/src/plugins/builtin/analytics/risk-book.ts +215 -0
  294. package/src/plugins/builtin/analytics/risk-client.ts +13 -6
  295. package/src/plugins/builtin/analytics/risk-headless.ts +55 -21
  296. package/src/plugins/builtin/analytics/risk-math.ts +6 -3
  297. package/src/plugins/builtin/analytics/risk-model.ts +297 -104
  298. package/src/plugins/builtin/analytics/risk-options.ts +17 -2
  299. package/src/plugins/builtin/analytics/risk-pane.tsx +97 -36
  300. package/src/plugins/builtin/attention/pane.tsx +6 -2
  301. package/src/plugins/builtin/awards/headless.ts +7 -3
  302. package/src/plugins/builtin/awards/model.ts +18 -0
  303. package/src/plugins/builtin/awards/pane.tsx +6 -3
  304. package/src/plugins/builtin/backtest/headless.ts +3 -3
  305. package/src/plugins/builtin/backtest/rules.ts +41 -5
  306. package/src/plugins/builtin/broker-manager/add-flow.tsx +12 -7
  307. package/src/plugins/builtin/broker-manager/detail.tsx +47 -19
  308. package/src/plugins/builtin/broker-manager/footer.ts +27 -11
  309. package/src/plugins/builtin/broker-manager/index.tsx +21 -12
  310. package/src/plugins/builtin/broker-manager/keyboard.ts +1 -1
  311. package/src/plugins/builtin/broker-manager/model.ts +12 -2
  312. package/src/plugins/builtin/broker-manager/pane-actions.tsx +183 -57
  313. package/src/plugins/builtin/broker-manager/table.ts +28 -12
  314. package/src/plugins/builtin/broker-trading/account-picker.tsx +2 -1
  315. package/src/plugins/builtin/broker-trading/chart-levels.ts +82 -13
  316. package/src/plugins/builtin/broker-trading/controller.ts +45 -13
  317. package/src/plugins/builtin/broker-trading/dock.tsx +22 -4
  318. package/src/plugins/builtin/broker-trading/headless.ts +2 -1
  319. package/src/plugins/builtin/broker-trading/index.tsx +7 -1
  320. package/src/plugins/builtin/broker-trading/linked-orders.ts +148 -0
  321. package/src/plugins/builtin/broker-trading/order-feed.ts +75 -7
  322. package/src/plugins/builtin/broker-trading/orders.tsx +109 -31
  323. package/src/plugins/builtin/broker-trading/overview-orders.tsx +9 -3
  324. package/src/plugins/builtin/broker-trading/pane-model.ts +30 -2
  325. package/src/plugins/builtin/broker-trading/pane.tsx +110 -23
  326. package/src/plugins/builtin/broker-trading/ticket-parts.tsx +36 -7
  327. package/src/plugins/builtin/broker-trading/ticket.tsx +112 -31
  328. package/src/plugins/builtin/buildout/cells.tsx +4 -0
  329. package/src/plugins/builtin/buildout/detail/index.tsx +5 -1
  330. package/src/plugins/builtin/buildout/detail/ui.tsx +7 -4
  331. package/src/plugins/builtin/buildout/pane/index.tsx +25 -12
  332. package/src/plugins/builtin/buildout/pane/status.tsx +0 -4
  333. package/src/plugins/builtin/builtin-plugin-meta.ts +1 -1
  334. package/src/plugins/builtin/catalysts/detail.tsx +3 -2
  335. package/src/plugins/builtin/catalysts/index.tsx +1 -1
  336. package/src/plugins/builtin/catalysts/model.ts +49 -4
  337. package/src/plugins/builtin/catalysts/pane.tsx +6 -8
  338. package/src/plugins/builtin/central-bank-rates/client.ts +5 -0
  339. package/src/plugins/builtin/central-bank-rates/headless.ts +36 -10
  340. package/src/plugins/builtin/central-bank-rates/model.ts +33 -8
  341. package/src/plugins/builtin/changelog/index.tsx +1 -0
  342. package/src/plugins/builtin/chart-composer/catalog-inventory.ts +1 -0
  343. package/src/plugins/builtin/chart-composer/chart-spec-edit.ts +2 -1
  344. package/src/plugins/builtin/chart-composer/chart-spec.ts +7 -0
  345. package/src/plugins/builtin/chart-composer/cli-options.ts +2 -5
  346. package/src/plugins/builtin/chart-composer/data-catalog-pane.tsx +2 -1
  347. package/src/plugins/builtin/chart-composer/editor/controller.ts +2 -0
  348. package/src/plugins/builtin/chart-composer/editor.tsx +4 -1
  349. package/src/plugins/builtin/chart-composer/headless-schema.ts +28 -26
  350. package/src/plugins/builtin/chart-composer/headless.ts +253 -35
  351. package/src/plugins/builtin/chart-composer/index.tsx +12 -2
  352. package/src/plugins/builtin/chart-composer/leverage-overlay.ts +142 -0
  353. package/src/plugins/builtin/chart-composer/pane.tsx +127 -28
  354. package/src/plugins/builtin/chart-composer/series-catalog.ts +1 -0
  355. package/src/plugins/builtin/chart-composer/series-expression.ts +65 -6
  356. package/src/plugins/builtin/chart-composer/session-history.ts +15 -21
  357. package/src/plugins/builtin/chart-composer/session-range.ts +4 -2
  358. package/src/plugins/builtin/chart-composer/settings.ts +31 -19
  359. package/src/plugins/builtin/chart-composer/use-series-catalog.ts +5 -6
  360. package/src/plugins/builtin/chart-composer/viewport-labels.ts +18 -8
  361. package/src/plugins/builtin/chat/attachments/model.ts +3 -1
  362. package/src/plugins/builtin/chat/content/index.tsx +1 -1
  363. package/src/plugins/builtin/chat/pane-links/open.ts +1 -1
  364. package/src/plugins/builtin/chat/people.ts +1 -1
  365. package/src/plugins/builtin/clinical-trials/client.ts +5 -2
  366. package/src/plugins/builtin/clinical-trials/model.ts +13 -4
  367. package/src/plugins/builtin/clinical-trials/pane.tsx +32 -12
  368. package/src/plugins/builtin/clinical-trials/ticker-sponsor.ts +17 -0
  369. package/src/plugins/builtin/cloud/askg/controller.ts +1 -1
  370. package/src/plugins/builtin/cloud/askg/lock-note.ts +1 -1
  371. package/src/plugins/builtin/cloud/askg/tool-display.ts +1 -1
  372. package/src/plugins/builtin/cloud/auth-commands.ts +3 -3
  373. package/src/plugins/builtin/cloud/team/pane-sections.tsx +105 -47
  374. package/src/plugins/builtin/cloud/team/pane-ui.tsx +42 -4
  375. package/src/plugins/builtin/cloud/team/pane.tsx +204 -64
  376. package/src/plugins/builtin/cloud/thesis/store.ts +45 -22
  377. package/src/plugins/builtin/cloud-tweets/registration.ts +1 -0
  378. package/src/plugins/builtin/commodities-energy/index.tsx +29 -2
  379. package/src/plugins/builtin/commodities-energy/view-state.ts +2 -0
  380. package/src/plugins/builtin/commodity-balances/pane.tsx +11 -4
  381. package/src/plugins/builtin/company-attention/app-rank.tsx +7 -5
  382. package/src/plugins/builtin/company-attention/building-model.ts +222 -0
  383. package/src/plugins/builtin/company-attention/building.tsx +172 -0
  384. package/src/plugins/builtin/company-attention/client.ts +117 -1
  385. package/src/plugins/builtin/company-attention/evidence.ts +16 -3
  386. package/src/plugins/builtin/company-attention/headless.ts +101 -5
  387. package/src/plugins/builtin/company-attention/index.tsx +6 -3
  388. package/src/plugins/builtin/company-attention/model.ts +33 -7
  389. package/src/plugins/builtin/company-attention/moves-model.ts +253 -0
  390. package/src/plugins/builtin/company-attention/moves.tsx +159 -0
  391. package/src/plugins/builtin/company-attention/pane.tsx +79 -23
  392. package/src/plugins/builtin/company-attention/signals-model.ts +229 -0
  393. package/src/plugins/builtin/company-attention/signals.tsx +160 -0
  394. package/src/plugins/builtin/company-kpis/headless.ts +3 -2
  395. package/src/plugins/builtin/company-kpis/model.ts +2 -2
  396. package/src/plugins/builtin/company-kpis/pane.tsx +1 -1
  397. package/src/plugins/builtin/composite-plugins.ts +2 -1
  398. package/src/plugins/builtin/congress-trades/headless.ts +1 -1
  399. package/src/plugins/builtin/connections/index.ts +1 -0
  400. package/src/plugins/builtin/correlation/headless-schema.ts +3 -2
  401. package/src/plugins/builtin/correlation/headless.ts +5 -3
  402. package/src/plugins/builtin/cot/headless.ts +28 -6
  403. package/src/plugins/builtin/cot/model.ts +12 -0
  404. package/src/plugins/builtin/cot/pane.tsx +3 -2
  405. package/src/plugins/builtin/cpi/headless.ts +5 -1
  406. package/src/plugins/builtin/cpi/pane.tsx +11 -9
  407. package/src/plugins/builtin/credit-boards/model.ts +2 -0
  408. package/src/plugins/builtin/credit-documents/headless.ts +1 -1
  409. package/src/plugins/builtin/crypto-board/client.ts +86 -0
  410. package/src/plugins/builtin/crypto-board/defi-view.tsx +218 -0
  411. package/src/plugins/builtin/crypto-board/defi.ts +239 -0
  412. package/src/plugins/builtin/crypto-board/headless.ts +117 -6
  413. package/src/plugins/builtin/crypto-board/index.tsx +8 -3
  414. package/src/plugins/builtin/crypto-board/model.ts +40 -8
  415. package/src/plugins/builtin/crypto-board/pane.tsx +55 -21
  416. package/src/plugins/builtin/crypto-board/series.ts +19 -1
  417. package/src/plugins/builtin/crypto-etf-flows/client.ts +60 -0
  418. package/src/plugins/builtin/crypto-etf-flows/headless.ts +132 -0
  419. package/src/plugins/builtin/crypto-etf-flows/index.tsx +44 -0
  420. package/src/plugins/builtin/crypto-etf-flows/model.ts +121 -0
  421. package/src/plugins/builtin/crypto-etf-flows/pane.tsx +193 -0
  422. package/src/plugins/builtin/debug/index.tsx +1 -0
  423. package/src/plugins/builtin/dividend-yield/index.tsx +1 -1
  424. package/src/plugins/builtin/docs/index.tsx +1 -1
  425. package/src/plugins/builtin/docs/pane.tsx +2 -2
  426. package/src/plugins/builtin/docs/targets.ts +1 -1
  427. package/src/plugins/builtin/doe/client.ts +5 -1
  428. package/src/plugins/builtin/doe/headless.ts +12 -6
  429. package/src/plugins/builtin/doe/model.ts +43 -6
  430. package/src/plugins/builtin/doe/pane.tsx +18 -11
  431. package/src/plugins/builtin/earnings/board-model.ts +13 -6
  432. package/src/plugins/builtin/earnings/board-table.ts +4 -1
  433. package/src/plugins/builtin/earnings/board.tsx +253 -50
  434. package/src/plugins/builtin/earnings/calendar-model.ts +188 -0
  435. package/src/plugins/builtin/earnings/calendar.tsx +338 -0
  436. package/src/plugins/builtin/earnings/client.ts +4 -3
  437. package/src/plugins/builtin/earnings/headless.ts +53 -15
  438. package/src/plugins/builtin/earnings/history-model.ts +53 -36
  439. package/src/plugins/builtin/earnings/index.tsx +15 -22
  440. package/src/plugins/builtin/earnings/model.ts +17 -12
  441. package/src/plugins/builtin/earnings/scope.ts +89 -0
  442. package/src/plugins/builtin/earnings-calls/calendar.tsx +310 -0
  443. package/src/plugins/builtin/earnings-calls/data.ts +146 -2
  444. package/src/plugins/builtin/earnings-calls/headless.ts +151 -9
  445. package/src/plugins/builtin/earnings-calls/index.tsx +3 -3
  446. package/src/plugins/builtin/earnings-calls/lock-note.ts +1 -1
  447. package/src/plugins/builtin/earnings-calls/pane.tsx +149 -31
  448. package/src/plugins/builtin/earnings-calls/upcoming.ts +195 -0
  449. package/src/plugins/builtin/earnings-ripple/pane.tsx +10 -5
  450. package/src/plugins/builtin/econ/calendar-model.ts +132 -20
  451. package/src/plugins/builtin/econ/detail-view.tsx +48 -10
  452. package/src/plugins/builtin/econ/fred-catalog.ts +23 -6
  453. package/src/plugins/builtin/econ/fred-series-map.ts +4 -0
  454. package/src/plugins/builtin/econ/index.tsx +112 -25
  455. package/src/plugins/builtin/econ/print-watch.ts +2 -1
  456. package/src/plugins/builtin/econ/types.ts +32 -1
  457. package/src/plugins/builtin/econ-statistics/client.ts +16 -3
  458. package/src/plugins/builtin/econ-statistics/defs.ts +4 -0
  459. package/src/plugins/builtin/econ-statistics/detail.tsx +2 -2
  460. package/src/plugins/builtin/econ-statistics/headless.ts +13 -2
  461. package/src/plugins/builtin/econ-statistics/index.tsx +3 -3
  462. package/src/plugins/builtin/econ-statistics/pane.tsx +2 -1
  463. package/src/plugins/builtin/econ-statistics/stats.ts +103 -0
  464. package/src/plugins/builtin/econ-statistics/view.ts +16 -1
  465. package/src/plugins/builtin/equity-screener/client.ts +21 -3
  466. package/src/plugins/builtin/equity-screener/headless.ts +68 -6
  467. package/src/plugins/builtin/equity-screener/live.ts +1 -1
  468. package/src/plugins/builtin/equity-screener/model.ts +6 -0
  469. package/src/plugins/builtin/equity-screener/pane.tsx +45 -10
  470. package/src/plugins/builtin/equity-screener/screen-check.ts +90 -0
  471. package/src/plugins/builtin/equity-screener/ticker-check.tsx +148 -0
  472. package/src/plugins/builtin/estimate-revisions/headless.ts +3 -1
  473. package/src/plugins/builtin/estimate-revisions/lock-note.ts +3 -3
  474. package/src/plugins/builtin/estimate-revisions/model.ts +8 -10
  475. package/src/plugins/builtin/exposure/headless.ts +51 -6
  476. package/src/plugins/builtin/exposure/index.tsx +28 -2
  477. package/src/plugins/builtin/exposure/model.ts +7 -0
  478. package/src/plugins/builtin/exposure/pane.tsx +6 -1
  479. package/src/plugins/builtin/fear-greed/index.tsx +1 -1
  480. package/src/plugins/builtin/filing-events/index.tsx +1 -1
  481. package/src/plugins/builtin/futures/model.ts +10 -9
  482. package/src/plugins/builtin/futures/returns.ts +8 -36
  483. package/src/plugins/builtin/futures/table.tsx +1 -1
  484. package/src/plugins/builtin/futures-curve/client.ts +40 -9
  485. package/src/plugins/builtin/futures-curve/headless.ts +39 -17
  486. package/src/plugins/builtin/futures-curve/model.ts +258 -69
  487. package/src/plugins/builtin/futures-curve/pane.tsx +46 -17
  488. package/src/plugins/builtin/fx-matrix/client.ts +15 -8
  489. package/src/plugins/builtin/fx-matrix/headless.ts +32 -14
  490. package/src/plugins/builtin/fx-matrix/index.tsx +13 -11
  491. package/src/plugins/builtin/fx-matrix/live-legs.ts +22 -0
  492. package/src/plugins/builtin/fx-matrix/settings.ts +2 -1
  493. package/src/plugins/builtin/gpu/headless.ts +9 -4
  494. package/src/plugins/builtin/help/index.tsx +13 -3
  495. package/src/plugins/builtin/holders/beneficial-model.ts +8 -11
  496. package/src/plugins/builtin/holders/beneficial-report.ts +6 -5
  497. package/src/plugins/builtin/holders/beneficial-view.tsx +7 -3
  498. package/src/plugins/builtin/holders/client.ts +13 -1
  499. package/src/plugins/builtin/holders/format.ts +28 -17
  500. package/src/plugins/builtin/holders/headless.ts +46 -7
  501. package/src/plugins/builtin/holders/index-holders.ts +264 -0
  502. package/src/plugins/builtin/holders/pane.tsx +79 -15
  503. package/src/plugins/builtin/holders/report-rows.ts +35 -7
  504. package/src/plugins/builtin/holders/table-model.ts +2 -1
  505. package/src/plugins/builtin/holders/treemap.tsx +2 -2
  506. package/src/plugins/builtin/insider/headless.ts +1 -1
  507. package/src/plugins/builtin/insider/signals-client.ts +1 -1
  508. package/src/plugins/builtin/insider/signals.tsx +1 -1
  509. package/src/plugins/builtin/ipo-calendar/pane.tsx +7 -4
  510. package/src/plugins/builtin/iv-history/client.ts +20 -0
  511. package/src/plugins/builtin/iv-history/headless.ts +4 -4
  512. package/src/plugins/builtin/iv-history/index.tsx +1 -1
  513. package/src/plugins/builtin/iv-history/model.ts +13 -4
  514. package/src/plugins/builtin/iv-history/series.ts +3 -1
  515. package/src/plugins/builtin/jobs/lock-note.ts +1 -1
  516. package/src/plugins/builtin/jobs/model.ts +4 -15
  517. package/src/plugins/builtin/jobs/pane.tsx +7 -5
  518. package/src/plugins/builtin/jobs/share-bars.tsx +11 -5
  519. package/src/plugins/builtin/jodi/pane.tsx +10 -4
  520. package/src/plugins/builtin/layout-manager/index.tsx +1 -0
  521. package/src/plugins/builtin/macro-day/headless.ts +20 -7
  522. package/src/plugins/builtin/macro-day/index.tsx +3 -2
  523. package/src/plugins/builtin/macro-day/model.ts +29 -8
  524. package/src/plugins/builtin/macro-day/pane.tsx +46 -10
  525. package/src/plugins/builtin/macro-day/releases.ts +55 -13
  526. package/src/plugins/builtin/market-heatmap/data.ts +9 -2
  527. package/src/plugins/builtin/market-heatmap/evidence.ts +1 -1
  528. package/src/plugins/builtin/market-heatmap/headless.ts +9 -6
  529. package/src/plugins/builtin/market-heatmap/index.tsx +3 -3
  530. package/src/plugins/builtin/market-heatmap/model.ts +10 -7
  531. package/src/plugins/builtin/market-movers/client.ts +33 -19
  532. package/src/plugins/builtin/market-movers/headless.ts +8 -2
  533. package/src/plugins/builtin/market-movers/index.tsx +16 -10
  534. package/src/plugins/builtin/market-movers/screener.ts +29 -8
  535. package/src/plugins/builtin/market-movers/session-body.tsx +4 -2
  536. package/src/plugins/builtin/market-movers/session-table.ts +4 -2
  537. package/src/plugins/builtin/market-movers/table.ts +4 -1
  538. package/src/plugins/builtin/market-valuation/headless.ts +2 -0
  539. package/src/plugins/builtin/market-valuation/view.ts +5 -0
  540. package/src/plugins/builtin/members/headless.ts +6 -5
  541. package/src/plugins/builtin/members/pane.tsx +11 -4
  542. package/src/plugins/builtin/mna/client.ts +1 -0
  543. package/src/plugins/builtin/mna/detail.tsx +20 -32
  544. package/src/plugins/builtin/mna/distress/detail.tsx +16 -4
  545. package/src/plugins/builtin/mna/distress/model.ts +3 -2
  546. package/src/plugins/builtin/mna/distress/pane.tsx +7 -4
  547. package/src/plugins/builtin/mna/headless.ts +6 -13
  548. package/src/plugins/builtin/mna/model.ts +93 -15
  549. package/src/plugins/builtin/mna/pane.tsx +5 -4
  550. package/src/plugins/builtin/news/headless.ts +12 -6
  551. package/src/plugins/builtin/news/index.tsx +10 -1
  552. package/src/plugins/builtin/news/wire/index.tsx +3 -2
  553. package/src/plugins/builtin/news/wire/news/command-bar-search.ts +26 -10
  554. package/src/plugins/builtin/news/wire/news/query-presets.ts +6 -2
  555. package/src/plugins/builtin/news/wire/rss/cli.ts +3 -3
  556. package/src/plugins/builtin/notes/cli.ts +49 -14
  557. package/src/plugins/builtin/openfda/pane.tsx +1 -1
  558. package/src/plugins/builtin/options/carry.ts +2 -2
  559. package/src/plugins/builtin/options/index.tsx +1 -1
  560. package/src/plugins/builtin/options/view.tsx +10 -10
  561. package/src/plugins/builtin/options-calculator/headless.ts +46 -7
  562. package/src/plugins/builtin/options-scenario/client.ts +123 -28
  563. package/src/plugins/builtin/options-scenario/collar.ts +8 -6
  564. package/src/plugins/builtin/options-scenario/csp-screen-headless.ts +127 -0
  565. package/src/plugins/builtin/options-scenario/csp-screen-pane.tsx +165 -0
  566. package/src/plugins/builtin/options-scenario/csp-screen.ts +258 -0
  567. package/src/plugins/builtin/options-scenario/csp.ts +101 -21
  568. package/src/plugins/builtin/options-scenario/headless.ts +36 -15
  569. package/src/plugins/builtin/options-scenario/hedge.ts +20 -14
  570. package/src/plugins/builtin/options-scenario/index.tsx +28 -3
  571. package/src/plugins/builtin/options-scenario/model.ts +13 -0
  572. package/src/plugins/builtin/options-scenario/pane.tsx +9 -5
  573. package/src/plugins/builtin/perps/equity-row.tsx +11 -3
  574. package/src/plugins/builtin/perps/freshness.ts +8 -5
  575. package/src/plugins/builtin/perps/headless.ts +3 -1
  576. package/src/plugins/builtin/perps/list-perpetuals.ts +25 -4
  577. package/src/plugins/builtin/perps/live-rows.ts +161 -0
  578. package/src/plugins/builtin/perps/markets-section.tsx +154 -0
  579. package/src/plugins/builtin/perps/pane.tsx +36 -17
  580. package/src/plugins/builtin/perps/venue-markets.ts +96 -0
  581. package/src/plugins/builtin/plugin-marketplace/index.tsx +2 -1
  582. package/src/plugins/builtin/plugin-marketplace/pane.tsx +143 -59
  583. package/src/plugins/builtin/portfolio-list/cli/bulk-symbols.ts +72 -24
  584. package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +158 -141
  585. package/src/plugins/builtin/portfolio-list/cli/render.ts +49 -20
  586. package/src/plugins/builtin/portfolio-list/cli/shared.ts +3 -3
  587. package/src/plugins/builtin/portfolio-list/cli/watchlist-command.ts +29 -24
  588. package/src/plugins/builtin/portfolio-list/headless.ts +6 -3
  589. package/src/plugins/builtin/portfolio-list/income.ts +13 -2
  590. package/src/plugins/builtin/portfolio-list/index.tsx +9 -2
  591. package/src/plugins/builtin/portfolio-list/pane/index.tsx +21 -8
  592. package/src/plugins/builtin/portfolio-list/pane/purchase-date-fx.ts +46 -0
  593. package/src/plugins/builtin/portfolio-list/summary/live-accounts.ts +16 -9
  594. package/src/plugins/builtin/portfolio-list/summary/totals.ts +2 -15
  595. package/src/plugins/builtin/power/client.ts +4 -1
  596. package/src/plugins/builtin/power/evidence.ts +22 -7
  597. package/src/plugins/builtin/power/gas.tsx +5 -1
  598. package/src/plugins/builtin/power/pane.tsx +8 -1
  599. package/src/plugins/builtin/power/prices.tsx +10 -3
  600. package/src/plugins/builtin/research/analyst-headless.ts +25 -8
  601. package/src/plugins/builtin/research/analyst-model.ts +68 -3
  602. package/src/plugins/builtin/research/corporate-actions-pane.tsx +63 -14
  603. package/src/plugins/builtin/research/event-model.ts +3 -1
  604. package/src/plugins/builtin/research/event-sources.ts +12 -4
  605. package/src/plugins/builtin/research/index.tsx +2 -1
  606. package/src/plugins/builtin/research/relative-valuation-basis.ts +58 -0
  607. package/src/plugins/builtin/research/relative-valuation-columns.ts +31 -2
  608. package/src/plugins/builtin/research/relative-valuation-currency.ts +12 -5
  609. package/src/plugins/builtin/research/relative-valuation-headless.ts +84 -26
  610. package/src/plugins/builtin/research/relative-valuation-model.ts +88 -19
  611. package/src/plugins/builtin/research/relative-valuation-pane.tsx +76 -9
  612. package/src/plugins/builtin/research/relative-valuation-peers.ts +1 -1
  613. package/src/plugins/builtin/reverse-dcf/model.ts +6 -2
  614. package/src/plugins/builtin/risk-factors/index.tsx +2 -2
  615. package/src/plugins/builtin/scanner/lock-note.ts +1 -1
  616. package/src/plugins/builtin/sec/forms.ts +13 -0
  617. package/src/plugins/builtin/sec/fund-abroad.ts +32 -0
  618. package/src/plugins/builtin/sec/fund-facts.ts +68 -8
  619. package/src/plugins/builtin/sec/headless.ts +85 -8
  620. package/src/plugins/builtin/sec/index.tsx +58 -12
  621. package/src/plugins/builtin/sectors/client.ts +2 -1
  622. package/src/plugins/builtin/sectors/sector-model.ts +11 -15
  623. package/src/plugins/builtin/series-inventory.ts +2 -0
  624. package/src/plugins/builtin/shared/broker-reconnect.ts +107 -22
  625. package/src/plugins/builtin/shared/cloud-upgrade.ts +34 -6
  626. package/src/plugins/builtin/shared/earnings-calendar.ts +375 -0
  627. package/src/plugins/builtin/{earnings/estimate-basis.ts → shared/earnings-estimate-basis.ts} +1 -1
  628. package/src/plugins/builtin/shared/earnings-report.ts +3 -3
  629. package/src/plugins/builtin/shared/fx-rate-freshness.ts +23 -1
  630. package/src/plugins/builtin/shared/job-posting.ts +129 -0
  631. package/src/plugins/builtin/shared/pro-lock-note.ts +3 -3
  632. package/src/plugins/builtin/shared/report-freshness.ts +3 -0
  633. package/src/plugins/builtin/shared/research-trading.tsx +21 -0
  634. package/src/plugins/builtin/shared/series-cache.ts +2 -0
  635. package/src/plugins/builtin/shared/ticker-surface.ts +2 -1
  636. package/src/plugins/builtin/short-interest/client.ts +2 -0
  637. package/src/plugins/builtin/short-interest/headless.ts +41 -12
  638. package/src/plugins/builtin/short-interest/index.tsx +23 -1
  639. package/src/plugins/builtin/short-interest/model.ts +70 -19
  640. package/src/plugins/builtin/short-interest/pane.tsx +19 -2
  641. package/src/plugins/builtin/short-interest/publications-client.ts +82 -0
  642. package/src/plugins/builtin/short-interest/publications-headless.ts +29 -0
  643. package/src/plugins/builtin/short-interest/publications-model.ts +50 -0
  644. package/src/plugins/builtin/short-interest/publications-pane.tsx +66 -0
  645. package/src/plugins/builtin/short-interest/schedule.ts +35 -2
  646. package/src/plugins/builtin/short-interest/surface.tsx +11 -4
  647. package/src/plugins/builtin/short-interest/types.ts +9 -0
  648. package/src/plugins/builtin/short-interest/watch-client.ts +14 -8
  649. package/src/plugins/builtin/short-interest/watch-model.ts +12 -25
  650. package/src/plugins/builtin/short-interest/watch-pane.tsx +5 -1
  651. package/src/plugins/builtin/supply-chain/flow.tsx +33 -9
  652. package/src/plugins/builtin/supply-chain/model.ts +51 -3
  653. package/src/plugins/builtin/supply-chain/pane.tsx +78 -39
  654. package/src/plugins/builtin/supply-chain/row-evidence.tsx +1 -1
  655. package/src/plugins/builtin/themes/headless.ts +8 -5
  656. package/src/plugins/builtin/themes/model.ts +14 -4
  657. package/src/plugins/builtin/themes/pane.tsx +24 -5
  658. package/src/plugins/builtin/thirteenf/headless.ts +5 -5
  659. package/src/plugins/builtin/thirteenf/signals.ts +3 -1
  660. package/src/plugins/builtin/ticker-detail/adr-pair/headless.ts +123 -0
  661. package/src/plugins/builtin/ticker-detail/adr-pair/model.ts +132 -0
  662. package/src/plugins/builtin/ticker-detail/adr-pair/tab.tsx +87 -0
  663. package/src/plugins/builtin/ticker-detail/data-panes/historical-prices.tsx +40 -26
  664. package/src/plugins/builtin/ticker-detail/data-panes/history-bars.ts +8 -4
  665. package/src/plugins/builtin/ticker-detail/data-panes/returns-history.ts +67 -3
  666. package/src/plugins/builtin/ticker-detail/data-panes/returns-model.ts +112 -5
  667. package/src/plugins/builtin/ticker-detail/data-panes/returns-pane.tsx +17 -2
  668. package/src/plugins/builtin/ticker-detail/financials/aggregation.ts +21 -7
  669. package/src/plugins/builtin/ticker-detail/financials/model.ts +36 -1
  670. package/src/plugins/builtin/ticker-detail/financials/offerings.ts +56 -0
  671. package/src/plugins/builtin/ticker-detail/financials/ratios.ts +62 -13
  672. package/src/plugins/builtin/ticker-detail/financials/tab.tsx +30 -4
  673. package/src/plugins/builtin/ticker-detail/headless-schema.ts +14 -2
  674. package/src/plugins/builtin/ticker-detail/headless.ts +148 -35
  675. package/src/plugins/builtin/ticker-detail/index.tsx +37 -5
  676. package/src/plugins/builtin/ticker-detail/overview/model.ts +65 -10
  677. package/src/plugins/builtin/ticker-detail/overview/pane.tsx +9 -1
  678. package/src/plugins/builtin/ticker-detail/overview-tab.tsx +68 -11
  679. package/src/plugins/builtin/ticker-detail/pane.tsx +11 -0
  680. package/src/plugins/builtin/ticker-detail/quote-footer.ts +8 -3
  681. package/src/plugins/builtin/ticker-detail/research-tabs.ts +11 -0
  682. package/src/plugins/builtin/vol-surface/client.ts +5 -4
  683. package/src/plugins/builtin/vol-surface/headless.ts +12 -3
  684. package/src/plugins/builtin/vol-surface/model.ts +4 -2
  685. package/src/plugins/builtin/volatility/model.ts +5 -10
  686. package/src/plugins/builtin/world-venue-map/basemap-layer.tsx +4 -3
  687. package/src/plugins/builtin/world-venue-map/basemap.ts +3 -1
  688. package/src/plugins/builtin/world-venue-map/chokepoint-chart.ts +40 -0
  689. package/src/plugins/builtin/world-venue-map/evidence.ts +1 -1
  690. package/src/plugins/builtin/world-venue-map/geo-series.ts +90 -11
  691. package/src/plugins/builtin/world-venue-map/headless.ts +1 -1
  692. package/src/plugins/builtin/world-venue-map/index.ts +3 -26
  693. package/src/plugins/builtin/world-venue-map/layers.ts +1 -1
  694. package/src/plugins/builtin/world-venue-map/map.tsx +2 -1
  695. package/src/plugins/builtin/world-venue-map/pane.tsx +4 -2
  696. package/src/plugins/builtin/world-venue-map/venue-header.tsx +15 -4
  697. package/src/plugins/builtin/yield-curve/client.ts +25 -0
  698. package/src/plugins/builtin/yield-curve/curves.ts +7 -4
  699. package/src/plugins/builtin/yield-curve/headless.ts +38 -4
  700. package/src/plugins/builtin/yield-curve/history.ts +4 -3
  701. package/src/plugins/builtin/yield-curve/index.tsx +12 -6
  702. package/src/plugins/builtin/yield-curve/swaps-model.ts +93 -0
  703. package/src/plugins/builtin/yield-curve/swaps.tsx +99 -0
  704. package/src/plugins/bundle.ts +1 -1
  705. package/src/plugins/catalog-browser.ts +2 -1
  706. package/src/plugins/compat.ts +3 -3
  707. package/src/plugins/dependencies.ts +75 -14
  708. package/src/plugins/extracted-plugins.ts +132 -34
  709. package/src/plugins/host-link.ts +149 -34
  710. package/src/plugins/installer.ts +35 -10
  711. package/src/plugins/loader.ts +206 -38
  712. package/src/plugins/manager-node.ts +2 -2
  713. package/src/plugins/marketplace/deactivation.ts +22 -0
  714. package/src/plugins/marketplace/model.ts +2 -2
  715. package/src/plugins/marketplace/packs.ts +1 -1
  716. package/src/plugins/ownership.ts +1 -1
  717. package/src/plugins/peer-retry.ts +155 -0
  718. package/src/plugins/registry/contributions.ts +3 -1
  719. package/src/plugins/registry/index.ts +4 -3
  720. package/src/plugins/registry/plugin-state.ts +3 -0
  721. package/src/plugins/seed-notice.ts +20 -0
  722. package/src/plugins/shortcut-argument.ts +39 -0
  723. package/src/portfolio/allocation.ts +1 -1
  724. package/src/portfolio/collection-name.ts +31 -0
  725. package/src/portfolio/column-values.ts +10 -8
  726. package/src/portfolio/cost-fx.ts +296 -19
  727. package/src/portfolio/manual-lots.ts +75 -0
  728. package/src/portfolio/mutations.ts +60 -22
  729. package/src/portfolio/suffixed-listings.ts +209 -0
  730. package/src/portfolio/totals-currency.ts +24 -0
  731. package/src/public/__snapshots__/public-api.test.ts.snap +14 -0
  732. package/src/public/time-series.ts +11 -8
  733. package/src/remote/schema.ts +1 -1
  734. package/src/renderers/browser/config-host.ts +3 -0
  735. package/src/renderers/browser/main.tsx +23 -3
  736. package/src/renderers/dom/boot-frame-page.ts +187 -0
  737. package/src/renderers/dom/boot-frame.ts +237 -0
  738. package/src/renderers/dom/build-assets.ts +46 -8
  739. package/src/renderers/dom/dom-ui-host.tsx +4 -29
  740. package/src/renderers/dom/host/ascii-text.ts +16 -2
  741. package/src/renderers/dom/host/box.tsx +43 -2
  742. package/src/renderers/dom/host/chart-surface.tsx +2 -0
  743. package/src/renderers/dom/host/hls.chunk.ts +3 -0
  744. package/src/renderers/dom/host/image-surface.tsx +49 -0
  745. package/src/renderers/dom/host/media-surface.tsx +24 -18
  746. package/src/renderers/dom/host/mouse.ts +30 -0
  747. package/src/renderers/dom/host/size-observer.ts +1 -1
  748. package/src/renderers/dom/host/style.ts +1 -1
  749. package/src/renderers/dom/styles.css +76 -0
  750. package/src/renderers/dom/test-utils.tsx +2 -1
  751. package/src/renderers/electrobun/bun/application-menu/index.ts +3 -3
  752. package/src/renderers/electrobun/bun/desktop/backend-requests.ts +3 -0
  753. package/src/renderers/electrobun/bun/desktop/backend.ts +46 -3
  754. package/src/renderers/electrobun/bun/desktop/detached-windows.ts +1 -1
  755. package/src/renderers/electrobun/bun/desktop/host-requests.ts +9 -3
  756. package/src/renderers/electrobun/bun/desktop/initialization.ts +81 -18
  757. package/src/renderers/electrobun/bun/external-plugins.ts +29 -7
  758. package/src/renderers/electrobun/bun/index.ts +11 -1
  759. package/src/renderers/electrobun/bun/window/boot-frame.ts +67 -0
  760. package/src/renderers/electrobun/bun/window/create.ts +4 -1
  761. package/src/renderers/electrobun/shared/boot-frame.ts +7 -0
  762. package/src/renderers/electrobun/shared/protocol.ts +6 -1
  763. package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +1 -1
  764. package/src/renderers/electrobun/view/config-host.ts +3 -0
  765. package/src/renderers/electrobun/view/fatal-screen.tsx +1 -1
  766. package/src/renderers/electrobun/view/main.tsx +30 -4
  767. package/src/renderers/electrobun/view/news-source.ts +5 -5
  768. package/src/renderers/electrobun/view/remote/asset-data-client.ts +1 -1
  769. package/src/renderers/electrobun/view/ui-host.tsx +1 -1
  770. package/src/renderers/opentui/browser-open.ts +88 -0
  771. package/src/renderers/opentui/host.tsx +5 -14
  772. package/src/renderers/opentui/image/loader.ts +3 -2
  773. package/src/renderers/opentui/native-smoke.ts +10 -1
  774. package/src/renderers/opentui/pane-image/index.ts +2 -1
  775. package/src/renderers/opentui/render-lib.ts +253 -0
  776. package/src/renderers/opentui/render-timing-smoke.ts +1 -1
  777. package/src/renderers/opentui/start.tsx +1 -1
  778. package/src/renderers/share/layout-view.tsx +2 -2
  779. package/src/renderers/share/main.tsx +4 -4
  780. package/src/renderers/share/view.tsx +1 -1
  781. package/src/series/resolve.ts +22 -6
  782. package/src/series/standalone.ts +30 -2
  783. package/src/series/types.ts +8 -1
  784. package/src/shares/api.ts +4 -1
  785. package/src/shares/pane.ts +1 -1
  786. package/src/sources/gloomberb-cloud/fred-series.ts +46 -1
  787. package/src/sources/gloomberb-cloud/index.ts +32 -16
  788. package/src/sources/gloomberb-cloud/news.ts +39 -0
  789. package/src/sources/gloomberb-cloud/normalizers.ts +14 -1
  790. package/src/sources/gloomberb-cloud/perpetuals.ts +49 -1
  791. package/src/sources/listing-symbols.ts +37 -0
  792. package/src/sources/provider-errors.ts +16 -2
  793. package/src/sources/provider-router/financial-routes.ts +21 -3
  794. package/src/sources/provider-router/financials.ts +15 -2
  795. package/src/sources/provider-router/history.ts +30 -8
  796. package/src/sources/provider-router/primary.ts +1 -1
  797. package/src/state/app/bootstrap.ts +23 -0
  798. package/src/state/hooks/inline-tickers.ts +30 -5
  799. package/src/sync/controller.ts +1 -1
  800. package/src/sync/core-contributors.ts +46 -14
  801. package/src/team/collections-sync.ts +2 -1
  802. package/src/team/collections.ts +178 -17
  803. package/src/telemetry/crash-reports.ts +17 -4
  804. package/src/test-support/builtin-panes.ts +1 -1
  805. package/src/theme/colors.ts +3 -30
  806. package/src/theme/ui-tokens.ts +37 -1
  807. package/src/tickers/company-name-listing.ts +210 -33
  808. package/src/tickers/index-roots.ts +47 -0
  809. package/src/tickers/instrument-label.ts +5 -1
  810. package/src/tickers/metadata.ts +10 -0
  811. package/src/tickers/perpetual-listing.ts +5 -2
  812. package/src/tickers/search/home-listing.ts +75 -0
  813. package/src/tickers/search/index.ts +76 -27
  814. package/src/tickers/search/ranking.ts +54 -4
  815. package/src/tickers/search/upsert.ts +29 -0
  816. package/src/tickers/terminal-codes.ts +416 -40
  817. package/src/time-series/bar-aggregation.ts +243 -0
  818. package/src/time-series/base-series.ts +307 -0
  819. package/src/time-series/chart-bounds.ts +349 -0
  820. package/src/time-series/chart-seed.ts +142 -0
  821. package/src/time-series/economic.ts +5 -0
  822. package/src/time-series/fundamentals.ts +18 -3
  823. package/src/time-series/history-acquisition.ts +499 -0
  824. package/src/time-series/leverage.ts +100 -0
  825. package/src/time-series/market-resolution.ts +4 -2
  826. package/src/time-series/market.ts +2 -1
  827. package/src/time-series/price-comparison.ts +175 -30
  828. package/src/time-series/range.ts +9 -1
  829. package/src/time-series/resolution.ts +174 -16
  830. package/src/time-series/resolve-context.ts +157 -0
  831. package/src/time-series/resolve.ts +126 -1577
  832. package/src/time-series/series-name.ts +38 -0
  833. package/src/time-series/series-presentation.ts +208 -0
  834. package/src/time-series/spec.ts +11 -6
  835. package/src/time-series/studies.ts +109 -12
  836. package/src/time-series/tail-reconcile.ts +121 -0
  837. package/src/time-series/types.ts +29 -2
  838. package/src/time-series/use-chart-resolution.ts +4 -5
  839. package/src/types/broker.ts +10 -0
  840. package/src/types/config.ts +14 -0
  841. package/src/types/data-provider.ts +14 -0
  842. package/src/types/exchange-rate.ts +6 -0
  843. package/src/types/financials.ts +104 -7
  844. package/src/types/headless.ts +76 -6
  845. package/src/types/instrument.ts +3 -0
  846. package/src/types/plugin.ts +65 -8
  847. package/src/types/price-history.ts +2 -0
  848. package/src/types/ticker.ts +13 -0
  849. package/src/types/trading.ts +59 -1
  850. package/src/ui/ascii-font.ts +13 -1
  851. package/src/ui/host.tsx +6 -1
  852. package/src/updater/command-names.ts +175 -0
  853. package/src/updater/index.ts +10 -5
  854. package/src/utils/calendar-date.ts +32 -15
  855. package/src/utils/cash-runway.ts +241 -0
  856. package/src/utils/central-banks.ts +42 -0
  857. package/src/utils/cli-output.ts +259 -80
  858. package/src/utils/contract-month.ts +16 -0
  859. package/src/utils/crypto-pair.ts +61 -3
  860. package/src/utils/currency-units.ts +29 -0
  861. package/src/utils/datetime-format.ts +10 -0
  862. package/src/utils/debug-log.ts +1 -1
  863. package/src/utils/decimal-comma.ts +39 -6
  864. package/src/utils/exchange-announcements.ts +71 -0
  865. package/src/utils/exchange-rate-snapshot.ts +10 -0
  866. package/src/utils/financial-statements.ts +83 -4
  867. package/src/utils/format.ts +34 -16
  868. package/src/utils/fundamentals.ts +150 -34
  869. package/src/utils/fx-market-hours.ts +10 -1
  870. package/src/utils/latest-financial-period.ts +8 -0
  871. package/src/utils/linux-libc.ts +54 -0
  872. package/src/utils/market-capitalization.ts +111 -15
  873. package/src/utils/max-drawdown.ts +64 -0
  874. package/src/utils/network-failure.ts +83 -0
  875. package/src/utils/option-expiry.ts +139 -7
  876. package/src/utils/price-earnings.ts +11 -5
  877. package/src/utils/price-history.ts +18 -8
  878. package/src/utils/price-window.ts +131 -0
  879. package/src/utils/release-date.ts +47 -0
  880. package/src/utils/sec.ts +3 -0
  881. package/src/utils/throttled-fetch.ts +11 -4
  882. package/src/utils/trailing-eps.ts +67 -0
  883. package/src/utils/typed-text.ts +21 -0
  884. package/src/utils/utc-time.ts +24 -1
  885. package/src/version.ts +6 -0
  886. package/src/cli/pane-functions/screenshot.ts +0 -2122
@@ -1,11 +1,12 @@
1
1
  import { useMemo, useState, type ReactNode } from "react";
2
2
  import { useThemeColors } from "../../theme/theme-context";
3
3
  import type { PricePoint } from "../../types/financials";
4
- import { Box } from "../../ui";
4
+ import { Box, useUiCapabilities } from "../../ui";
5
5
  import { compareSortValues, nextHeaderSort, type SortPreference } from "../../utils/sort-values";
6
6
  import { DataTableStackView } from "../data-table/stack-view";
7
7
  import { PriceSparkline } from "../price-sparkline/view";
8
8
  import { PaneStatusBody, StatGrid, statGridRows, type DataTableColumn, type DataTableCell, type StatItem } from "../ui";
9
+ import { withCountryFlag, withFlagRoom } from "../ui/country-flag";
9
10
  import { getTableWidth } from "../ui/table-layout";
10
11
 
11
12
  export interface MarketBoardRow {
@@ -13,6 +14,11 @@ export interface MarketBoardRow {
13
14
  label: string;
14
15
  /** Secondary name shown beside the label, such as the instrument a jurisdiction sets. */
15
16
  labelDetail?: string;
17
+ /**
18
+ * The country the row is (a jurisdiction, a sovereign), as a code or a
19
+ * name: its flag leads the label on the desktop and the web.
20
+ */
21
+ country?: string | null;
16
22
  value: number | null;
17
23
  valueText: string;
18
24
  change: number | null;
@@ -138,6 +144,8 @@ export function MarketBoardStack<T extends MarketBoardRow>({ rows, width, height
138
144
  labelWidth = 18, labelHeader = "INSTRUMENT", labelDetailHeader = "DETAIL", labelDetailWidth = 22, valueLabel = "LEVEL", percentileLabel = "PCTL 1Y", asOfWidth = 10, signedChange = false, extraColumns,
139
145
  rootBefore, emptyTitle = "No observations." }: MarketBoardStackProps<T>) {
140
146
  const colors = useThemeColors();
147
+ // A board of countries leads each name with its flag where one is drawn.
148
+ const flagged = useUiCapabilities().nativePaneChrome === true && rows.some((row) => row.country !== undefined);
141
149
  const [sort, setSort] = useState<SortPreference<string>>({ columnId: null, direction: "asc" });
142
150
  const items = useMemo(() => sort.columnId ? [...rows].sort((a, b) => {
143
151
  const key = sort.columnId as "label" | "labelDetail" | "value" | "change" | "percentile" | "asOf" | "changeAsOf";
@@ -149,7 +157,7 @@ export function MarketBoardStack<T extends MarketBoardRow>({ rows, width, height
149
157
  // A stale or partial row's date carries a word, so the column has room for both and the date is never cut.
150
158
  const wordWidth = Math.max(0, ...rows.map((row) => (row.status ? STATUS_WORDS[row.status]?.length : 0) ?? 0));
151
159
  const { columns, shortAsOf } = fitBoardColumns([
152
- { id: "label", label: labelHeader, width: labelWidth, align: "left" },
160
+ withFlagRoom({ id: "label", label: labelHeader, width: labelWidth, align: "left" }, flagged),
153
161
  ...(rows.some((row) => row.labelDetail !== undefined)
154
162
  ? [{ id: "labelDetail", label: labelDetailHeader, width: labelDetailWidth, align: "left" as const }] : []),
155
163
  { id: "value", label: valueLabel, width: valueWidth, align: "right" },
@@ -164,7 +172,7 @@ export function MarketBoardStack<T extends MarketBoardRow>({ rows, width, height
164
172
  const extra = extraColumns?.find((item) => item.column.id === column.id);
165
173
  if (extra) return extra.renderCell(row);
166
174
  const muted = row.status === "unavailable" ? colors.textDim : colors.text;
167
- if (column.id === "label") return { text: row.label, color: muted };
175
+ if (column.id === "label") return withCountryFlag({ text: row.label, color: muted }, row.country, flagged);
168
176
  if (column.id === "labelDetail") return { text: row.labelDetail ?? "", color: colors.textMuted };
169
177
  if (column.id === "value") return { text: row.valueText, color: muted };
170
178
  if (column.id === "change") return { text: row.changeText,
@@ -161,6 +161,7 @@ function useOnboardingWizard({ pluginRegistry, importBrokerPositions, onComplete
161
161
  importBrokerPositions,
162
162
  getConfig: () => stateRef.current.config,
163
163
  createBrokerInstance: (brokerType, label, values) => pluginRegistry.createBrokerInstance(brokerType, label, values),
164
+ enableBrokerInstance: (instanceId) => pluginRegistry.updateBrokerInstance(instanceId, {}, { enabled: true }),
164
165
  onSynced: handleBrokerSynced,
165
166
  setEditingField,
166
167
  setPortfolioSub,
@@ -91,13 +91,13 @@ export function BrokerSetupPanel({
91
91
  <Text fg={colors.textDim}>{t(" Enable \"ActiveX and Socket Clients\"")}</Text>
92
92
  </Box>
93
93
  <Box height={desktop ? 1 : 2} overflow="hidden">
94
- <Text fg={colors.textDim}>{t(" Gloomberb can auto-detect local API ports (4001, 4002, 7496, 7497)")}</Text>
94
+ <Text fg={colors.textDim}>{t(" Gloom can auto-detect local API ports (4001, 4002, 7496, 7497)")}</Text>
95
95
  </Box>
96
96
  <Box height={desktop ? 1 : 2} overflow="hidden">
97
97
  <Text fg={colors.textDim}>{t(" Use Manual setup only if you need a custom host or exact socket port")}</Text>
98
98
  </Box>
99
99
  <Box height={1}>
100
- <Text fg={colors.textDim}>{t("4. Keep it running while using Gloomberb")}</Text>
100
+ <Text fg={colors.textDim}>{t("4. Keep it running while using Gloom")}</Text>
101
101
  </Box>
102
102
  <Box height={desktop ? 2 : 1} />
103
103
  <GuideLink url={IBKR_GATEWAY_DOWNLOAD_URL} />
@@ -59,6 +59,7 @@ export function useOnboardingBrokerSync({
59
59
  importBrokerPositions,
60
60
  getConfig,
61
61
  createBrokerInstance,
62
+ enableBrokerInstance,
62
63
  onSynced,
63
64
  setEditingField,
64
65
  setPortfolioSub,
@@ -71,6 +72,7 @@ export function useOnboardingBrokerSync({
71
72
  /** The live config and profile creation, for the signed-in path that Add Broker shares. */
72
73
  getConfig: () => AppConfig;
73
74
  createBrokerInstance: (brokerType: string, label: string, values: Record<string, unknown>) => Promise<BrokerInstanceConfig>;
75
+ enableBrokerInstance: (instanceId: string) => Promise<void>;
74
76
  onSynced: (result: SyncBrokerInstanceResult, config: AppConfig) => void | Promise<void>;
75
77
  setEditingField: (editing: boolean) => void;
76
78
  setPortfolioSub: Dispatch<SetStateAction<PortfolioSub>>;
@@ -227,6 +229,7 @@ export function useOnboardingBrokerSync({
227
229
  const connected = await connectSignedInBrokerProfile(broker, {
228
230
  getConfig,
229
231
  createBrokerInstance,
232
+ enableBrokerInstance,
230
233
  syncBrokerInstance: (instanceId) => {
231
234
  if (brokerSyncAttemptRef.current === attemptId) showSyncing();
232
235
  return importInto(instanceId, attemptId, abortController.signal);
@@ -237,7 +240,7 @@ export function useOnboardingBrokerSync({
237
240
  } catch (error) {
238
241
  failSync(attemptId, error);
239
242
  }
240
- }, [beginAttempt, createBrokerInstance, failSync, finishSync, getConfig, importInto, setEditingField, showSyncing]);
243
+ }, [beginAttempt, createBrokerInstance, enableBrokerInstance, failSync, finishSync, getConfig, importInto, setEditingField, showSyncing]);
241
244
 
242
245
  const syncSelectedBroker = useCallback(async (brokerValueOverrides?: Record<string, string>) => {
243
246
  const signedIn = brokerOptions.find((option) => option.id === selectedBrokerId)?.signedIn;
@@ -1,13 +1,13 @@
1
1
  import { Box, Text } from "../../ui";
2
2
  import { useEffect, useId, type ReactNode } from "react";
3
- import type { PaneSettingField } from "../../types/plugin";
3
+ import type { PaneSettingField, PaneSettingRowNote } from "../../types/plugin";
4
4
  import { colors } from "../../theme/colors";
5
5
  import { SelectField, type SelectFieldHandle } from "../ui/select-field";
6
6
  import { Checkbox } from "../ui/checkbox";
7
7
  import { Button } from "../ui/button";
8
8
  import { Badge } from "../ui/display";
9
9
  import { DialogFrame } from "../ui/frame";
10
- import { isPaneSettingDisabled, summarizePaneSettingValue } from "./value";
10
+ import { isPaneSettingDisabled, noteColor, summarizePaneSettingValue } from "./value";
11
11
 
12
12
  const DESKTOP_TEXT_STYLE = {
13
13
  letterSpacing: 0,
@@ -74,6 +74,7 @@ function DesktopSettingsRow({
74
74
  field,
75
75
  selected,
76
76
  currentValue,
77
+ note,
77
78
  onHover,
78
79
  onEdit,
79
80
  onSelectRef,
@@ -82,6 +83,8 @@ function DesktopSettingsRow({
82
83
  field: PaneSettingField;
83
84
  selected: boolean;
84
85
  currentValue: unknown;
86
+ /** What its action said on it: the state beside its button, the reason in place of its description. */
87
+ note: PaneSettingRowNote | null;
85
88
  onHover: () => void;
86
89
  onEdit: () => void;
87
90
  onSelectRef: (fieldKey: string, element: SelectFieldHandle | null) => void;
@@ -91,6 +94,7 @@ function DesktopSettingsRow({
91
94
  const disabled = isPaneSettingDisabled(field);
92
95
  const rowId = useFollowHighlight(selected);
93
96
  const summary = summarizePaneSettingValue(field, currentValue);
97
+ const description = note?.text ?? field.description;
94
98
  const control = field.type === "toggle" ? (
95
99
  <Checkbox label={field.label} displayLabel="" checked={currentValue === true} onChange={(checked) => onApply(field, checked)} />
96
100
  ) : field.type === "select" ? (
@@ -104,7 +108,10 @@ function DesktopSettingsRow({
104
108
  />
105
109
  ) : field.type === "action" ? (
106
110
  // The button says what pressing the row does, and presses it: the row's own press is not repeated.
107
- <Button label={summary} variant="secondary" disabled={disabled} onPress={onEdit} stopPropagation />
111
+ <Box flexDirection="row" alignItems="center" gap={1}>
112
+ {note ? <Text fg={noteColor(note)} style={desktopText()}>{note.status}</Text> : null}
113
+ <Button label={summary} variant="secondary" disabled={disabled} onPress={onEdit} stopPropagation />
114
+ </Box>
108
115
  ) : (
109
116
  <Box flexDirection="row" alignItems="center" gap={1}>
110
117
  <Badge label={summary} />
@@ -116,7 +123,7 @@ function DesktopSettingsRow({
116
123
  <Box
117
124
  id={rowId}
118
125
  flexDirection="column"
119
- minHeight={field.description ? undefined : 2}
126
+ minHeight={description ? undefined : 2}
120
127
  data-gloom-role="pane-setting-row"
121
128
  data-selected={selected ? "true" : "false"}
122
129
  backgroundColor={selected ? "var(--gloom-hover-fill)" : "transparent"}
@@ -143,9 +150,9 @@ function DesktopSettingsRow({
143
150
  </Box>
144
151
  {control}
145
152
  </Box>
146
- {field.description && (
147
- <Text fg={colors.textMuted} wrapText style={desktopText()}>
148
- {field.description}
153
+ {description && (
154
+ <Text fg={note?.text ? noteColor(note) : colors.textMuted} wrapText style={desktopText()}>
155
+ {description}
149
156
  </Text>
150
157
  )}
151
158
  </Box>
@@ -156,6 +163,7 @@ function DesktopSettingsList({
156
163
  fields,
157
164
  selectedIndex,
158
165
  settings,
166
+ noteFor,
159
167
  onHover,
160
168
  onEdit,
161
169
  onSelectRef,
@@ -164,6 +172,7 @@ function DesktopSettingsList({
164
172
  fields: PaneSettingField[];
165
173
  selectedIndex: number;
166
174
  settings: Record<string, unknown>;
175
+ noteFor?: (field: PaneSettingField) => PaneSettingRowNote | null;
167
176
  onHover: (field: PaneSettingField, index: number) => void;
168
177
  onEdit: (field: PaneSettingField, index: number) => void;
169
178
  onSelectRef: (fieldKey: string, element: SelectFieldHandle | null) => void;
@@ -182,6 +191,7 @@ function DesktopSettingsList({
182
191
  field={field}
183
192
  selected={index === selectedIndex}
184
193
  currentValue={settings[field.key]}
194
+ note={noteFor?.(field) ?? null}
185
195
  onHover={() => onHover(field, index)}
186
196
  onEdit={() => onEdit(field, index)}
187
197
  onSelectRef={onSelectRef}
@@ -208,6 +218,7 @@ export function DesktopPaneSettingsDialogBody({
208
218
  fields,
209
219
  selectedIndex,
210
220
  settings,
221
+ noteFor,
211
222
  onHover,
212
223
  onEdit,
213
224
  onSelectRef,
@@ -218,6 +229,7 @@ export function DesktopPaneSettingsDialogBody({
218
229
  fields: PaneSettingField[];
219
230
  selectedIndex: number;
220
231
  settings: Record<string, unknown>;
232
+ noteFor?: (field: PaneSettingField) => PaneSettingRowNote | null;
221
233
  onHover: (field: PaneSettingField, index: number) => void;
222
234
  onEdit: (field: PaneSettingField, index: number) => void;
223
235
  onSelectRef: (fieldKey: string, element: SelectFieldHandle | null) => void;
@@ -237,6 +249,7 @@ export function DesktopPaneSettingsDialogBody({
237
249
  fields={fields}
238
250
  selectedIndex={selectedIndex}
239
251
  settings={settings}
252
+ noteFor={noteFor}
240
253
  onHover={onHover}
241
254
  onEdit={onEdit}
242
255
  onSelectRef={onSelectRef}
@@ -1,12 +1,12 @@
1
1
  import { Box, Text } from "../../ui";
2
2
  import { t } from "../../i18n";
3
3
  import { TextAttributes } from "../../ui";
4
- import type { PaneSettingField } from "../../types/plugin";
4
+ import type { PaneSettingField, PaneSettingRowNote } from "../../types/plugin";
5
5
  import { colors } from "../../theme/colors";
6
6
  import { useViewport } from "../../react/input";
7
7
  import { DialogFrame, ListView } from "../ui";
8
8
  import type { ListViewProps } from "../ui/list-view";
9
- import { isPaneSettingDisabled, summarizePaneSettingValue } from "./value";
9
+ import { isPaneSettingDisabled, noteColor, summarizePaneSettingValue } from "./value";
10
10
 
11
11
  /** Terminal rows a settings dialog spends around its list: edge, frame, title, description. */
12
12
  const TUI_DIALOG_LIST_CHROME_ROWS = 11;
@@ -21,7 +21,10 @@ export function useTuiDialogListRows(): number {
21
21
  * for it scrolls to the cursor instead of running under the dialog's edge,
22
22
  * and the highlighted row's description sits under it.
23
23
  */
24
- export function TuiDialogList(props: ListViewProps) {
24
+ export function TuiDialogList({ descriptionColor, ...props }: ListViewProps & {
25
+ /** The highlighted row's description in a tone: what its action ran into. */
26
+ descriptionColor?: (index: number) => string | undefined;
27
+ }) {
25
28
  const maxRows = useTuiDialogListRows();
26
29
  const scrollable = props.items.length > maxRows;
27
30
  const description = props.selectedIndex >= 0 ? props.items[props.selectedIndex]?.description : undefined;
@@ -37,7 +40,7 @@ export function TuiDialogList(props: ListViewProps) {
37
40
  <>
38
41
  <Box height={1} />
39
42
  <Box>
40
- <Text fg={colors.textDim}>{" "}{t(description)}</Text>
43
+ <Text fg={descriptionColor?.(props.selectedIndex) ?? colors.textDim}>{" "}{t(description)}</Text>
41
44
  </Box>
42
45
  </>
43
46
  )}
@@ -58,6 +61,7 @@ export function TuiPaneSettingsDialogBody({
58
61
  fields,
59
62
  selectedIndex,
60
63
  settings,
64
+ noteFor,
61
65
  onSelect,
62
66
  onActivate,
63
67
  }: {
@@ -65,26 +69,30 @@ export function TuiPaneSettingsDialogBody({
65
69
  fields: PaneSettingField[];
66
70
  selectedIndex: number;
67
71
  settings: Record<string, unknown>;
72
+ /** What an action said on its own row: its state in place of the row's value, its reason in place of the description. */
73
+ noteFor?: (field: PaneSettingField) => PaneSettingRowNote | null;
68
74
  onSelect: (index: number) => void;
69
75
  onActivate: (field: PaneSettingField | undefined) => void;
70
76
  }) {
77
+ const notes = fields.map((field) => noteFor?.(field) ?? null);
71
78
  return (
72
79
  <DialogFrame title={t(title)}>
73
80
  <TuiDialogList
74
- items={fields.map((field) => ({
81
+ items={fields.map((field, index) => ({
75
82
  id: field.key,
76
83
  label: t(field.label),
77
- description: field.description ? t(field.description) : field.description,
78
- detail: summarizePaneSettingValue(field, settings[field.key]),
84
+ description: notes[index]?.text ?? (field.description ? t(field.description) : field.description),
85
+ detail: notes[index]?.status ?? summarizePaneSettingValue(field, settings[field.key]),
79
86
  disabled: isPaneSettingDisabled(field),
80
87
  }))}
88
+ descriptionColor={(index) => (notes[index]?.text ? noteColor(notes[index]) : undefined)}
81
89
  selectedIndex={selectedIndex}
82
90
  bgColor={colors.commandBg}
83
91
  onSelect={onSelect}
84
92
  onActivate={(_, index) => {
85
93
  onActivate(fields[index]);
86
94
  }}
87
- renderRow={(item, rowState) => (
95
+ renderRow={(item, rowState, index) => (
88
96
  <Box flexDirection="row" justifyContent="space-between" width="100%">
89
97
  <Box flexDirection="row">
90
98
  <Text fg={rowState.selected ? colors.selectedText : colors.textDim}>
@@ -97,7 +105,7 @@ export function TuiPaneSettingsDialogBody({
97
105
  {item.label}
98
106
  </Text>
99
107
  </Box>
100
- <Text fg={colors.textMuted}>
108
+ <Text fg={noteColor(notes[index]) ?? colors.textMuted}>
101
109
  {item.detail}
102
110
  </Text>
103
111
  </Box>
@@ -1,5 +1,6 @@
1
- import type { PaneSettingField } from "../../types/plugin";
1
+ import type { PaneSettingField, PaneSettingRowNote } from "../../types/plugin";
2
2
  import { t } from "../../i18n";
3
+ import { colors } from "../../theme/colors";
3
4
 
4
5
  export function isSpaceKey(event: { name?: string; sequence?: string }): boolean {
5
6
  return event.name === "space" || event.name === " " || event.sequence === " ";
@@ -10,6 +11,12 @@ export function isPaneSettingDisabled(field: PaneSettingField): boolean {
10
11
  return field.type === "action" && field.disabled === true;
11
12
  }
12
13
 
14
+ /** A row note's tone, for its state and its reason. */
15
+ export function noteColor(note: PaneSettingRowNote | null | undefined): string | undefined {
16
+ if (!note) return undefined;
17
+ return note.tone === "negative" ? colors.negative : colors.warning;
18
+ }
19
+
13
20
  export function summarizePaneSettingValue(field: PaneSettingField, value: unknown): string {
14
21
  switch (field.type) {
15
22
  case "action":
@@ -1,7 +1,7 @@
1
1
  import { useUiCapabilities } from "../ui";
2
2
  import { type AlertContext, useDialog, useDialogKeyboard } from "../ui/dialog";
3
3
  import { useEffect, useRef, useState } from "react";
4
- import type { PaneSettingField } from "../types/plugin";
4
+ import type { PaneSettingField, PaneSettingRowNote } from "../types/plugin";
5
5
  import type { PluginRegistry } from "../plugins/registry";
6
6
  import { isPlainKey } from "../utils/keyboard";
7
7
  import { openSelectField, type SelectFieldHandle } from "./ui/select-field";
@@ -20,6 +20,13 @@ import {
20
20
  TuiUnavailablePaneSettingsDialog,
21
21
  } from "./pane-settings-dialog/tui";
22
22
  import { isPaneSettingDisabled, isSpaceKey, stepPaneSettingSelect } from "./pane-settings-dialog/value";
23
+ import { useRowNotes } from "./ui/row-notes";
24
+
25
+ const fieldKey = (field: PaneSettingField) => field.key;
26
+ /** What an action row shows of its own state: a note on it goes once that moves on (it connected elsewhere, say). */
27
+ const actionRowSignature = (field: PaneSettingField) => (
28
+ field.type === "action" ? `${field.actionLabel ?? ""}\u0000${field.description ?? ""}\u0000${field.disabled === true}` : ""
29
+ );
23
30
 
24
31
  interface PaneSettingsDialogContentProps extends AlertContext {
25
32
  paneId: string;
@@ -48,6 +55,11 @@ export function PaneSettingsDialogContent({
48
55
  });
49
56
  const [, setSettingsRevision] = useState(0);
50
57
  const desktopSelectRefs = useRef(new Map<string, SelectFieldHandle>());
58
+ // What an action said on its own row (setRowNote), while the dialog is open.
59
+ const { noteFor, setNote: setRowNote } = useRowNotes<PaneSettingField, PaneSettingRowNote>(fields, { key: fieldKey, signature: actionRowSignature });
60
+ const running = useRef(new Set<string>());
61
+ const mounted = useRef(true);
62
+ useEffect(() => () => { mounted.current = false; }, []);
51
63
 
52
64
  useEffect(() => {
53
65
  if (selectedIndex < fields.length) return;
@@ -68,24 +80,41 @@ export function PaneSettingsDialogContent({
68
80
  const openFieldEditor = async (field: PaneSettingField | undefined) => {
69
81
  if (!field || !descriptor) return;
70
82
  if (field.type === "action") {
71
- if (field.disabled) return;
83
+ // A row whose action is still running is not run again.
84
+ if (field.disabled || running.current.has(field.key)) return;
72
85
  let closed = false;
73
86
  const close = () => {
74
87
  if (closed) return;
75
88
  closed = true;
76
89
  dismiss();
77
90
  };
78
- await field.action({
79
- ...descriptor.context,
80
- surface: "pane-dialog",
81
- close,
82
- openCommandBar: (query) => {
83
- close();
84
- queueMicrotask(() => pluginRegistry.openCommandBar(query));
85
- },
86
- notify: (notification) => pluginRegistry.notify(notification),
87
- });
88
- if (!closed) setSettingsRevision((revision) => revision + 1);
91
+ running.current.add(field.key);
92
+ setRowNote(field.key, null);
93
+ try {
94
+ await field.action({
95
+ ...descriptor.context,
96
+ surface: "pane-dialog",
97
+ close,
98
+ openCommandBar: (query) => {
99
+ close();
100
+ queueMicrotask(() => pluginRegistry.openCommandBar(query));
101
+ },
102
+ notify: (notification) => pluginRegistry.notify(notification),
103
+ setRowNote: (note) => {
104
+ // The row is off screen once the dialog has closed, or once its field has left the settings (an
105
+ // account that disconnected and has nothing left to connect). The settings are read again here, as
106
+ // the action may have changed them since the dialog last drew.
107
+ if (closed || !mounted.current) return false;
108
+ const current = pluginRegistry.resolvePaneSettings(paneId)?.settingsDef.fields ?? [];
109
+ if (!current.some((entry) => entry.key === field.key)) return false;
110
+ setRowNote(field.key, note);
111
+ return true;
112
+ },
113
+ });
114
+ } finally {
115
+ running.current.delete(field.key);
116
+ }
117
+ if (!closed && mounted.current) setSettingsRevision((revision) => revision + 1);
89
118
  return;
90
119
  }
91
120
  const currentValue = descriptor.context.settings[field.key];
@@ -191,6 +220,7 @@ export function PaneSettingsDialogContent({
191
220
  fields={fields}
192
221
  selectedIndex={selectedIndex}
193
222
  settings={descriptor.context.settings}
223
+ noteFor={noteFor}
194
224
  onHover={(_field, index) => setSelectedIndex(index)}
195
225
  onSelectRef={setDesktopSelectRef}
196
226
  onEdit={(field, index) => {
@@ -208,6 +238,7 @@ export function PaneSettingsDialogContent({
208
238
  fields={fields}
209
239
  selectedIndex={selectedIndex}
210
240
  settings={descriptor.context.settings}
241
+ noteFor={noteFor}
211
242
  onSelect={setSelectedIndex}
212
243
  onActivate={(field) => {
213
244
  void openFieldEditor(field).catch(() => {});
@@ -42,7 +42,14 @@ export function desktopQrModulePx(modules: number, availablePx: number, cellHeig
42
42
  }
43
43
 
44
44
  interface SignInCodePanelProps {
45
+ /** The page the browser button opens. */
45
46
  url: string | null;
47
+ /**
48
+ * The link shown and drawn as the QR code, when it differs from `url`: a
49
+ * short link that leads to the same page. Null shows neither, for a page
50
+ * whose own address is too long to read or scan. Defaults to `url`.
51
+ */
52
+ link?: string | null;
46
53
  /**
47
54
  * A code to show under the QR code: Gloom's own sign-in compares it with
48
55
  * the page it opens. A broker connect shows none.
@@ -62,10 +69,10 @@ interface SignInCodePanelProps {
62
69
 
63
70
  /**
64
71
  * A browser hand-off: button, QR code, an optional short code, the URL, and a
65
- * live status. Used to sign in to Gloom and to connect a broker. Degrades by
66
- * height: the QR needs its full module grid in the terminal, so short
67
- * terminals drop decoration first and finally fall back to the URL (and code),
68
- * which works over SSH too. The desktop draws the QR as an image in whole
72
+ * live status. Used to sign in to Gloom, to connect a broker and to finish a
73
+ * Pro checkout. Degrades by height: the QR needs its full module grid in the
74
+ * terminal, so short terminals drop decoration first and finally fall back to
75
+ * the URL (and code), which works over SSH too. The desktop draws the QR as an image in whole
69
76
  * pixel modules, smaller when the rows run out.
70
77
  */
71
78
  export function SignInCodePanel(props: SignInCodePanelProps) {
@@ -86,17 +93,18 @@ export function SignInCodePanel(props: SignInCodePanelProps) {
86
93
  }} />
87
94
  )
88
95
  : null;
96
+ const link = props.link === undefined ? url : props.link;
89
97
  return desktop
90
- ? <DesktopPanel {...props} button={button} />
91
- : <TerminalPanel {...props} button={button} />;
98
+ ? <DesktopPanel {...props} link={link} button={button} />
99
+ : <TerminalPanel {...props} link={link} button={button} />;
92
100
  }
93
101
 
94
- type PanelBodyProps = SignInCodePanelProps & { button: React.ReactNode };
102
+ type PanelBodyProps = Omit<SignInCodePanelProps, "link"> & { link: string | null; button: React.ReactNode };
95
103
 
96
104
  /** Laid out by the browser: a QR image in whole-pixel modules, the code as a figure. */
97
- function DesktopPanel({ url, code, status, height, button }: PanelBodyProps) {
105
+ function DesktopPanel({ link, code, status, height, button }: PanelBodyProps) {
98
106
  const { cellHeightPx = 18 } = useUiCapabilities();
99
- const qr = useMemo(() => (url ? renderQrSvgDataUri(url) : null), [url]);
107
+ const qr = useMemo(() => (link ? renderQrSvgDataUri(link) : null), [link]);
100
108
  const besideQr = DESKTOP_ROWS_BESIDE_QR + (code ? DESKTOP_CODE_ROWS : 0);
101
109
  const modulePx = qr ? desktopQrModulePx(qr.modules, (height - besideQr) * cellHeightPx, cellHeightPx) : null;
102
110
  const qrPx = qr && modulePx ? modulePx * qr.modules : 0;
@@ -119,7 +127,7 @@ function DesktopPanel({ url, code, status, height, button }: PanelBodyProps) {
119
127
  }}
120
128
  />
121
129
  )}
122
- {url && !qrPx && (
130
+ {link && !qrPx && (
123
131
  <Box marginTop={1}>
124
132
  <Text fg={colors.textDim}>{t("Not enough room to draw the QR code.")}</Text>
125
133
  </Box>
@@ -129,9 +137,9 @@ function DesktopPanel({ url, code, status, height, button }: PanelBodyProps) {
129
137
  <FigureText>{code}</FigureText>
130
138
  </Box>
131
139
  )}
132
- {url && (
140
+ {link && (
133
141
  <Box marginTop={code ? 0 : 1} maxWidth="100%">
134
- <Text fg={colors.textMuted} wrapText selectable style={{ textAlign: "center" }}>{url}</Text>
142
+ <Text fg={colors.textMuted} wrapText selectable style={{ textAlign: "center" }}>{link}</Text>
135
143
  </Box>
136
144
  )}
137
145
  <Box marginTop={1}>
@@ -142,16 +150,16 @@ function DesktopPanel({ url, code, status, height, button }: PanelBodyProps) {
142
150
  }
143
151
 
144
152
  /** Laid out in cells: half-block QR lines need their full grid, so short terminals drop rows first. */
145
- function TerminalPanel({ url, code, status, height, button }: PanelBodyProps) {
146
- const qrLines = useMemo(() => (url ? renderQrLines(url) : []), [url]);
153
+ function TerminalPanel({ link, code, status, height, button }: PanelBodyProps) {
154
+ const qrLines = useMemo(() => (link ? renderQrLines(link) : []), [link]);
147
155
  // Reserve the browser button before fitting the QR, code, and status.
148
- const contentHeight = height - (url ? 2 : 0);
156
+ const contentHeight = height - (button ? 2 : 0);
149
157
  const codeRows = code ? 1 : 0;
150
158
  const showQr = qrLines.length > 0 && contentHeight >= qrLines.length + codeRows + 1;
151
159
  const qrRows = showQr ? qrLines.length : 0;
152
160
  // A blank row before the code, the link and the status when there is room.
153
- const spacious = showQr && contentHeight >= qrRows + codeRows * 2 + (url ? 2 : 0) + 2;
154
- const showUrl = !!url && (!showQr || spacious || contentHeight >= qrRows + codeRows + 2);
161
+ const spacious = showQr && contentHeight >= qrRows + codeRows * 2 + (link ? 2 : 0) + 2;
162
+ const showUrl = !!link && (!showQr || spacious || contentHeight >= qrRows + codeRows + 2);
155
163
 
156
164
  return (
157
165
  <Box flexDirection="column" alignItems="center">
@@ -165,7 +173,7 @@ function TerminalPanel({ url, code, status, height, button }: PanelBodyProps) {
165
173
  ))}
166
174
  </Box>
167
175
  )}
168
- {!showQr && url && (
176
+ {!showQr && link && (
169
177
  <Box height={1}>
170
178
  <Text fg={colors.textDim}>{t("Not enough room to draw the QR code.")}</Text>
171
179
  </Box>
@@ -182,7 +190,7 @@ function TerminalPanel({ url, code, status, height, button }: PanelBodyProps) {
182
190
  <>
183
191
  {spacious && <Box height={1} />}
184
192
  <Box height={1}>
185
- <Text fg={colors.textMuted}>{url}</Text>
193
+ <Text fg={colors.textMuted}>{link}</Text>
186
194
  </Box>
187
195
  </>
188
196
  )}
@@ -1,8 +1,9 @@
1
1
  import type { CSSProperties, ReactNode } from "react";
2
2
  import { Box, Text, useUiCapabilities } from "../../ui";
3
+ import { hoverBg } from "../../theme/colors";
3
4
  import { useThemeColors } from "../../theme/theme-context";
4
5
  import { displayWidth, padTo, truncateToDisplayWidth } from "../../utils/format";
5
- import { ExternalLinkText } from "./external-link";
6
+ import { ExternalLinkText, usePaneLinkMenuEntry } from "./external-link";
6
7
 
7
8
  /** One column of a ColumnGrid. */
8
9
  export interface ColumnGridColumn {
@@ -20,9 +21,19 @@ export interface ColumnGridColumn {
20
21
  gapBefore?: number;
21
22
  }
22
23
 
24
+ /**
25
+ * What a cell's text opens (a row's market, a security's DES): the text is the
26
+ * target, as a key-value row's value is, and inside a `PaneLinkMenu` the pane
27
+ * menu lists it as `label`, so the keyboard reaches what a click opens.
28
+ */
29
+ export interface ColumnGridLink {
30
+ label: string;
31
+ onOpen: () => void;
32
+ }
33
+
23
34
  /** Text the grid fits to its column (padded on the terminal, cut by CSS on the desktop), or content the column holds. */
24
35
  export type ColumnGridCell =
25
- | { text: string; color?: string }
36
+ | { text: string; color?: string; link?: ColumnGridLink }
26
37
  | { content: ReactNode }
27
38
  | null;
28
39
 
@@ -76,6 +87,35 @@ function gridTemplate(columns: readonly ColumnGridColumn[]): { template: string;
76
87
  return { template: tracks.join(" "), gap: undefined, lines };
77
88
  }
78
89
 
90
+ /** A link cell's pointer handling and its pane-menu entry; nothing for a plain cell. */
91
+ function useLinkTarget(link: ColumnGridLink | undefined) {
92
+ const colors = useThemeColors();
93
+ usePaneLinkMenuEntry(link ? `column-grid:${link.label}` : null, link?.label ?? "", () => link?.onOpen());
94
+ return link ? {
95
+ cursor: "pointer" as const,
96
+ hoverBackgroundColor: hoverBg(colors),
97
+ onMouseDown: (event?: { button?: number }) => { if ((event?.button ?? 0) === 0) link.onOpen(); },
98
+ "data-gloom-interactive": "true",
99
+ "data-gloom-label": link.label,
100
+ } : {};
101
+ }
102
+
103
+ /** A text cell that opens something, in the terminal: its padded text is the target. */
104
+ function TerminalLinkCell({ text, color, link, width, align }: { text: string; color?: string; link: ColumnGridLink; width: number; align?: "left" | "right" }) {
105
+ const target = useLinkTarget(link);
106
+ return <Box width={width} flexDirection="row" {...target}><Text fg={color}>{padTo(text, width, align)}</Text></Box>;
107
+ }
108
+
109
+ /** A text cell that opens something, on the desktop and the web. */
110
+ function NativeLinkCell({ text, color, link, column, place }: { text: string; color?: string; link: ColumnGridLink; column: ColumnGridColumn; place: CSSProperties }) {
111
+ const target = useLinkTarget(link);
112
+ return (
113
+ <Text fg={color} data-gloom-ui="column-grid-text" {...clipOf(text, column)} {...target} style={{ ...place, ...TEXT_BOX, textAlign: column.align ?? "left" }}>
114
+ {text}
115
+ </Text>
116
+ );
117
+ }
118
+
79
119
  /**
80
120
  * Columns of single-line text that line up from row to row: a table of
81
121
  * figures under its header, or label and value pairs set in columns. The terminal lays the
@@ -83,7 +123,8 @@ function gridTemplate(columns: readonly ColumnGridColumn[]): { template: string;
83
123
  * them. The desktop and the web lay out one CSS grid whose tracks are counted
84
124
  * in characters, so the columns follow a resize to the pixel, every row and
85
125
  * the header share the same tracks, and text that does not fit ends in an
86
- * ellipsis instead of being cut to a count of cells.
126
+ * ellipsis instead of being cut to a count of cells. A text cell with a `link`
127
+ * opens it on a click and is listed in the pane menu.
87
128
  */
88
129
  export function ColumnGrid({ columns, rows, width, role }: ColumnGridProps) {
89
130
  const { nativePaneChrome } = useUiCapabilities();
@@ -98,7 +139,9 @@ export function ColumnGrid({ columns, rows, width, role }: ColumnGridProps) {
98
139
  <Box key={index} flexDirection="row">
99
140
  {column.gapBefore ? <Box width={column.gapBefore} /> : null}
100
141
  {cell && "text" in cell
101
- ? <Text fg={cell.color}>{padTo(cell.text, column.width, column.align)}</Text>
142
+ ? cell.link
143
+ ? <TerminalLinkCell text={cell.text} color={cell.color} link={cell.link} width={column.width} align={column.align} />
144
+ : <Text fg={cell.color}>{padTo(cell.text, column.width, column.align)}</Text>
102
145
  : <Box width={column.width} flexDirection="row">{cell?.content}</Box>}
103
146
  </Box>
104
147
  );
@@ -126,6 +169,7 @@ export function ColumnGrid({ columns, rows, width, role }: ColumnGridProps) {
126
169
  const cell = row[index] ?? null;
127
170
  if (!cell) return null;
128
171
  const place: CSSProperties = { gridColumn: lines[index], gridRow: rowIndex + 1 };
172
+ if ("text" in cell && cell.link) return <NativeLinkCell key={index} text={cell.text} color={cell.color} link={cell.link} column={column} place={place} />;
129
173
  return "text" in cell
130
174
  ? (
131
175
  <Text