gloomberb 0.16.6 → 0.17.0

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 (348) hide show
  1. package/package.json +2 -1
  2. package/src/api-client/chat-pane-link.ts +47 -0
  3. package/src/api-client/chat.ts +9 -1
  4. package/src/api-client/data.ts +37 -1
  5. package/src/api-client/equity-screener.ts +3 -0
  6. package/src/api-client/europe-energy.ts +91 -0
  7. package/src/api-client/index.ts +6 -0
  8. package/src/api-client/letters.ts +41 -0
  9. package/src/api-client/normalizers.ts +36 -6
  10. package/src/api-client/organization-tickers.ts +44 -0
  11. package/src/api-client/request.ts +3 -1
  12. package/src/api-client/types.ts +27 -1
  13. package/src/app/runtime/desktop-deeplink.ts +48 -15
  14. package/src/architecture/core-builtin-allowlist.json +1 -1
  15. package/src/architecture/dom-cell-metrics-allowlist.json +28 -0
  16. package/src/ask-gloom/pane-context.ts +23 -19
  17. package/src/ask-gloom/pane-request.ts +2 -2
  18. package/src/cli/commands/fred-series.ts +77 -11
  19. package/src/cli/commands/market.ts +77 -20
  20. package/src/cli/commands/overview.ts +29 -20
  21. package/src/cli/commands/ticker.ts +64 -11
  22. package/src/cli/desktop-pane-shot-view.ts +114 -0
  23. package/src/cli/desktop-pane-shot.ts +30 -31
  24. package/src/cli/entry.ts +7 -0
  25. package/src/cli/export-source.ts +43 -0
  26. package/src/cli/freshness.ts +18 -3
  27. package/src/cli/glossary.ts +17 -0
  28. package/src/cli/history-rows.ts +174 -13
  29. package/src/cli/known-gaps.ts +14 -3
  30. package/src/cli/listing-arg.ts +20 -2
  31. package/src/cli/listing-suggestion.ts +159 -0
  32. package/src/cli/native-smoke.ts +13 -0
  33. package/src/cli/not-a-ticker.ts +13 -1
  34. package/src/cli/pane-functions/capabilities.ts +16 -8
  35. package/src/cli/pane-functions/dom.ts +28 -13
  36. package/src/cli/pane-functions/function-help.ts +51 -6
  37. package/src/cli/pane-functions/headless.ts +26 -7
  38. package/src/cli/pane-functions/index.ts +46 -3
  39. package/src/cli/pane-functions/report-notices.ts +6 -3
  40. package/src/cli/pane-functions/report.ts +16 -2
  41. package/src/cli/pane-functions/resolver.ts +7 -4
  42. package/src/cli/report-tables.ts +31 -7
  43. package/src/cli/result.ts +54 -11
  44. package/src/cli/symbol-rows.ts +18 -1
  45. package/src/components/chart/composite/axis-overlays.tsx +2 -0
  46. package/src/components/chart/composite/composite-chart.tsx +4 -21
  47. package/src/components/chart/composite/legend.tsx +10 -6
  48. package/src/components/chart/composite/price-axis-labels.tsx +1 -0
  49. package/src/components/command-bar/list/model.ts +2 -0
  50. package/src/components/command-bar/pane-templates/items.ts +1 -1
  51. package/src/components/command-bar/routes/ticker-search/actions.ts +1 -0
  52. package/src/components/command-bar/routes/ticker-search/results.ts +3 -1
  53. package/src/components/command-bar/workflow/ops.ts +8 -97
  54. package/src/components/command-bar/workflow/pane-reuse.ts +177 -0
  55. package/src/components/data-table/view.tsx +1 -0
  56. package/src/components/feed-data-table/stack-view.tsx +18 -42
  57. package/src/components/layout/missing-pane.tsx +2 -0
  58. package/src/components/layout/shell/index.tsx +1 -0
  59. package/src/components/layout/shell/pane/ask.ts +12 -7
  60. package/src/components/layout/shell/pane/capture.ts +8 -34
  61. package/src/components/markdown-text.tsx +37 -6
  62. package/src/components/reader/article-reader.tsx +91 -266
  63. package/src/components/reader/detail-reader.tsx +210 -0
  64. package/src/components/reader/reader-text.tsx +239 -0
  65. package/src/components/table-view-shared.tsx +8 -4
  66. package/src/components/ticker/badge/list.tsx +15 -4
  67. package/src/components/ui/choice-dialog.tsx +3 -0
  68. package/src/components/ui/data-table/types.ts +7 -0
  69. package/src/components/ui/detail-scroll-body.tsx +31 -4
  70. package/src/components/ui/display.tsx +46 -1
  71. package/src/components/ui/icon.tsx +11 -1
  72. package/src/components/ui/list-view.tsx +3 -1
  73. package/src/components/ui/query-bar-keys.tsx +2 -0
  74. package/src/components/ui/query-bar.tsx +9 -1
  75. package/src/components/ui/select-button.tsx +3 -0
  76. package/src/data/config/store/fold-panes.ts +202 -11
  77. package/src/data/config/store/migrations.ts +13 -1
  78. package/src/docs/snapshot.json +29 -0
  79. package/src/i18n/es.ts +14 -0
  80. package/src/i18n/ja.ts +14 -0
  81. package/src/i18n/ko.ts +14 -0
  82. package/src/i18n/zh-cn.ts +14 -0
  83. package/src/i18n/zh-tw.ts +14 -0
  84. package/src/layout/desk-keys.ts +7 -0
  85. package/src/layout/desks.ts +2 -2
  86. package/src/market-data/market/status.ts +67 -6
  87. package/src/market-data/quotes/contributions.ts +15 -0
  88. package/src/market-data/quotes/regular-session-valuation.ts +131 -0
  89. package/src/market-data/quotes/resolution.ts +4 -0
  90. package/src/market-data/snapshot-provider.ts +6 -3
  91. package/src/notifications/app-badge.ts +30 -0
  92. package/src/plugins/builtin/account-management/calendar-tab.tsx +1 -1
  93. package/src/plugins/builtin/account-management/form-components.tsx +53 -1
  94. package/src/plugins/builtin/account-management/keyboard.ts +5 -0
  95. package/src/plugins/builtin/account-management/model.ts +27 -0
  96. package/src/plugins/builtin/account-management/pane.tsx +62 -2
  97. package/src/plugins/builtin/alerts/cli.ts +6 -4
  98. package/src/plugins/builtin/analytics/index.tsx +1 -1
  99. package/src/plugins/builtin/awards/pane.tsx +29 -18
  100. package/src/plugins/builtin/backtest/pane.tsx +2 -1
  101. package/src/plugins/builtin/bond-calculator/index.tsx +3 -5
  102. package/src/plugins/builtin/buildout/detail/company.tsx +7 -4
  103. package/src/plugins/builtin/builtin-plugin-meta.ts +5 -4
  104. package/src/plugins/builtin/catalysts/model.ts +92 -10
  105. package/src/plugins/builtin/catalysts/pane.tsx +6 -4
  106. package/src/plugins/builtin/cds/index.tsx +21 -30
  107. package/src/plugins/builtin/changelog/index.tsx +11 -12
  108. package/src/plugins/builtin/chart-composer/headless-schema.ts +2 -0
  109. package/src/plugins/builtin/chart-composer/headless.ts +87 -5
  110. package/src/plugins/builtin/chart-composer/pane.tsx +3 -2
  111. package/src/plugins/builtin/chart-composer/session-history.ts +20 -5
  112. package/src/plugins/builtin/chat/command-bar.ts +6 -8
  113. package/src/plugins/builtin/chat/content/composer-runtime.ts +2 -2
  114. package/src/plugins/builtin/chat/content/composer.tsx +13 -4
  115. package/src/plugins/builtin/chat/content/footer.tsx +15 -5
  116. package/src/plugins/builtin/chat/content/handle-prompt.tsx +326 -0
  117. package/src/plugins/builtin/chat/content/index.tsx +113 -9
  118. package/src/plugins/builtin/chat/content/layout-metrics.ts +4 -0
  119. package/src/plugins/builtin/chat/content/open-targets.ts +20 -4
  120. package/src/plugins/builtin/chat/content/scroll.ts +6 -1
  121. package/src/plugins/builtin/chat/content/transcript.tsx +11 -2
  122. package/src/plugins/builtin/chat/ghost-user.ts +1 -1
  123. package/src/plugins/builtin/chat/handle-prompt.ts +128 -0
  124. package/src/plugins/builtin/chat/index.tsx +44 -21
  125. package/src/plugins/builtin/chat/layout.ts +7 -14
  126. package/src/plugins/builtin/chat/message/desktop.tsx +59 -11
  127. package/src/plugins/builtin/chat/message/header.tsx +69 -21
  128. package/src/plugins/builtin/chat/message/pane-chip.tsx +223 -0
  129. package/src/plugins/builtin/chat/message/person-icons.tsx +53 -0
  130. package/src/plugins/builtin/chat/message/profile-popover.tsx +73 -9
  131. package/src/plugins/builtin/chat/message/render-state.ts +15 -2
  132. package/src/plugins/builtin/chat/message/terminal.tsx +33 -8
  133. package/src/plugins/builtin/chat/message/types.ts +3 -0
  134. package/src/plugins/builtin/chat/pane-links/model.ts +149 -0
  135. package/src/plugins/builtin/chat/pane-links/open.ts +29 -0
  136. package/src/plugins/builtin/chat/pane-links/previews.ts +119 -0
  137. package/src/plugins/builtin/chat/pane-state.ts +5 -8
  138. package/src/plugins/builtin/chat/people.ts +202 -0
  139. package/src/plugins/builtin/chat/profile-popover.ts +18 -2
  140. package/src/plugins/builtin/chat/status-widget.tsx +3 -8
  141. package/src/plugins/builtin/chat/unread-badge.ts +65 -0
  142. package/src/plugins/builtin/chat/unread-inbox-pane.tsx +9 -6
  143. package/src/plugins/builtin/clinical-trials/client.ts +26 -1
  144. package/src/plugins/builtin/clinical-trials/index.tsx +10 -2
  145. package/src/plugins/builtin/clinical-trials/model.ts +269 -0
  146. package/src/plugins/builtin/clinical-trials/pane.tsx +247 -62
  147. package/src/plugins/builtin/clinical-trials/sponsor-tickers.ts +156 -0
  148. package/src/plugins/builtin/cloud/askg/attached-pane.tsx +3 -3
  149. package/src/plugins/builtin/cloud/askg/pane-attachment.ts +3 -3
  150. package/src/plugins/builtin/cloud/mcp-connect/dialog.tsx +1 -0
  151. package/src/plugins/builtin/comment-letters/pane.tsx +30 -11
  152. package/src/plugins/builtin/commodities-energy/index.tsx +179 -0
  153. package/src/plugins/builtin/commodity-balances/client.ts +208 -0
  154. package/src/plugins/builtin/commodity-balances/headless.ts +66 -0
  155. package/src/plugins/builtin/commodity-balances/index.tsx +32 -0
  156. package/src/plugins/builtin/commodity-balances/model.ts +261 -0
  157. package/src/plugins/builtin/commodity-balances/pane.tsx +227 -0
  158. package/src/plugins/builtin/composite-plugins.ts +26 -1
  159. package/src/plugins/builtin/credit-boards/index.tsx +21 -42
  160. package/src/plugins/builtin/credit-boards/model.ts +0 -2
  161. package/src/plugins/builtin/credit-conditions/index.tsx +10 -19
  162. package/src/plugins/builtin/credit-documents/index.tsx +27 -10
  163. package/src/plugins/builtin/debt-maturities/index.tsx +3 -17
  164. package/src/plugins/builtin/debug/index.tsx +2 -2
  165. package/src/plugins/builtin/dividend-yield/client.ts +3 -1
  166. package/src/plugins/builtin/dividend-yield/headless.ts +3 -1
  167. package/src/plugins/builtin/dividend-yield/pane.tsx +3 -1
  168. package/src/plugins/builtin/dividend-yield/provider-client.ts +3 -1
  169. package/src/plugins/builtin/docs/blocks.tsx +4 -3
  170. package/src/plugins/builtin/docs/pane.tsx +16 -8
  171. package/src/plugins/builtin/earnings/index.tsx +2 -0
  172. package/src/plugins/builtin/earnings-calls/pane.tsx +2 -12
  173. package/src/plugins/builtin/equity-screener/client.ts +1 -1
  174. package/src/plugins/builtin/equity-screener/headless.ts +36 -2
  175. package/src/plugins/builtin/equity-screener/model.ts +121 -68
  176. package/src/plugins/builtin/executives/pane.tsx +3 -1
  177. package/src/plugins/builtin/filing-events/index.tsx +20 -0
  178. package/src/plugins/builtin/fixed-income/index.tsx +46 -0
  179. package/src/plugins/builtin/fixed-income/model.ts +27 -0
  180. package/src/plugins/builtin/fixed-income/pane.tsx +162 -0
  181. package/src/plugins/builtin/fixed-income/shortcut.ts +52 -0
  182. package/src/plugins/builtin/futures/index.tsx +24 -7
  183. package/src/plugins/builtin/futures/series.ts +23 -2
  184. package/src/plugins/builtin/futures/use-front-returns.ts +3 -2
  185. package/src/plugins/builtin/futures-curve/pane.tsx +6 -4
  186. package/src/plugins/builtin/help/shortcut-table.tsx +4 -2
  187. package/src/plugins/builtin/insider/detail.tsx +20 -12
  188. package/src/plugins/builtin/insider/index.tsx +2 -2
  189. package/src/plugins/builtin/iv-history/index.tsx +3 -0
  190. package/src/plugins/builtin/iv-history/screen-pane.tsx +13 -5
  191. package/src/plugins/builtin/jodi/client.ts +220 -0
  192. package/src/plugins/builtin/jodi/headless.ts +63 -0
  193. package/src/plugins/builtin/jodi/index.tsx +32 -0
  194. package/src/plugins/builtin/jodi/model.ts +75 -0
  195. package/src/plugins/builtin/jodi/pane.tsx +141 -0
  196. package/src/plugins/builtin/market-heatmap/evidence.ts +13 -4
  197. package/src/plugins/builtin/market-heatmap/headless.ts +3 -3
  198. package/src/plugins/builtin/market-heatmap/index.tsx +41 -23
  199. package/src/plugins/builtin/market-heatmap/live.ts +2 -1
  200. package/src/plugins/builtin/market-heatmap/portfolio.ts +67 -21
  201. package/src/plugins/builtin/market-movers/table.ts +2 -2
  202. package/src/plugins/builtin/market-valuation/align.ts +10 -9
  203. package/src/plugins/builtin/mna/distress/model.ts +52 -1
  204. package/src/plugins/builtin/mna/distress/pane.tsx +17 -12
  205. package/src/plugins/builtin/mna/index.tsx +2 -0
  206. package/src/plugins/builtin/news/wire/index.tsx +2 -2
  207. package/src/plugins/builtin/news/wire/industry-pane.tsx +28 -14
  208. package/src/plugins/builtin/news/wire/letters/client.ts +108 -0
  209. package/src/plugins/builtin/news/wire/letters/model.ts +69 -0
  210. package/src/plugins/builtin/news/wire/letters/pane.tsx +155 -0
  211. package/src/plugins/builtin/news/wire/mutes.ts +2 -1
  212. package/src/plugins/builtin/news/wire/news/query-presets.ts +4 -1
  213. package/src/plugins/builtin/openfda/client.ts +123 -15
  214. package/src/plugins/builtin/openfda/model.ts +163 -0
  215. package/src/plugins/builtin/openfda/pane.tsx +109 -65
  216. package/src/plugins/builtin/openfda/types.ts +25 -0
  217. package/src/plugins/builtin/options/view.tsx +1 -1
  218. package/src/plugins/builtin/pe-band/model.ts +3 -2
  219. package/src/plugins/builtin/plugin-marketplace/pane.tsx +1 -1
  220. package/src/plugins/builtin/plugin-module.ts +3 -1
  221. package/src/plugins/builtin/portfolio-list/cli/bulk-symbols.ts +1 -1
  222. package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +19 -4
  223. package/src/plugins/builtin/portfolio-list/cli/render.ts +2 -2
  224. package/src/plugins/builtin/portfolio-list/cli/shared.ts +39 -0
  225. package/src/plugins/builtin/portfolio-list/cli/watchlist-command.ts +18 -5
  226. package/src/plugins/builtin/portfolio-list/live-valuation.ts +25 -13
  227. package/src/plugins/builtin/power/evidence.ts +32 -3
  228. package/src/plugins/builtin/power/gas-client.ts +110 -0
  229. package/src/plugins/builtin/power/gas-model.ts +194 -0
  230. package/src/plugins/builtin/power/gas.tsx +145 -0
  231. package/src/plugins/builtin/power/headless.ts +4 -1
  232. package/src/plugins/builtin/power/index.tsx +19 -9
  233. package/src/plugins/builtin/power/pane.tsx +2 -3
  234. package/src/plugins/builtin/power/prices-headless.ts +75 -7
  235. package/src/plugins/builtin/power/prices.tsx +36 -13
  236. package/src/plugins/builtin/primary-dealers/client.ts +108 -0
  237. package/src/plugins/builtin/primary-dealers/headless.ts +53 -0
  238. package/src/plugins/builtin/primary-dealers/index.tsx +17 -0
  239. package/src/plugins/builtin/primary-dealers/model.ts +206 -0
  240. package/src/plugins/builtin/primary-dealers/pane.tsx +149 -0
  241. package/src/plugins/builtin/relative-rotation/index.tsx +3 -0
  242. package/src/plugins/builtin/research/analyst-model.ts +9 -5
  243. package/src/plugins/builtin/research/headless-schema.ts +2 -1
  244. package/src/plugins/builtin/research/relative-valuation-headless.ts +68 -32
  245. package/src/plugins/builtin/research/relative-valuation-model.ts +45 -24
  246. package/src/plugins/builtin/research/relative-valuation-pane.tsx +39 -4
  247. package/src/plugins/builtin/scanner/flow-pane.tsx +8 -1
  248. package/src/plugins/builtin/sec/filing-display.tsx +3 -36
  249. package/src/plugins/builtin/sec/index.tsx +131 -43
  250. package/src/plugins/builtin/sec/model.ts +148 -2
  251. package/src/plugins/builtin/sec/row-summaries.ts +105 -0
  252. package/src/plugins/builtin/sectors/index.tsx +2 -0
  253. package/src/plugins/builtin/sectors/sector-model.ts +2 -2
  254. package/src/plugins/builtin/series-inventory.ts +1 -0
  255. package/src/plugins/builtin/shared/locked-rows.tsx +1 -1
  256. package/src/plugins/builtin/shared/use-quote-board.ts +179 -43
  257. package/src/plugins/builtin/shared/wall-teaser.tsx +2 -2
  258. package/src/plugins/builtin/shared/zip-text.ts +46 -0
  259. package/src/plugins/builtin/short-interest/watch-model.ts +11 -2
  260. package/src/plugins/builtin/themes/model.ts +2 -2
  261. package/src/plugins/builtin/ticker-detail/financials/aggregation.ts +11 -0
  262. package/src/plugins/builtin/ticker-detail/financials/ratios.ts +81 -19
  263. package/src/plugins/builtin/ticker-detail/financials/tab.tsx +1 -1
  264. package/src/plugins/builtin/ticker-detail/headless.ts +2 -2
  265. package/src/plugins/builtin/ticker-detail/overview/model.ts +3 -1
  266. package/src/plugins/builtin/ticker-detail/overview-tab.tsx +7 -5
  267. package/src/plugins/builtin/ticker-detail/quote-monitor/card.tsx +8 -6
  268. package/src/plugins/builtin/time-sales/headless.ts +22 -0
  269. package/src/plugins/builtin/trace-bonds/client.ts +196 -0
  270. package/src/plugins/builtin/trace-bonds/headless.ts +69 -0
  271. package/src/plugins/builtin/trace-bonds/index.tsx +33 -0
  272. package/src/plugins/builtin/trace-bonds/model.ts +115 -0
  273. package/src/plugins/builtin/trace-bonds/pane.tsx +191 -0
  274. package/src/plugins/builtin/treasury-auctions/index.tsx +33 -47
  275. package/src/plugins/builtin/treasury-daily/client.ts +96 -0
  276. package/src/plugins/builtin/treasury-daily/headless.ts +69 -0
  277. package/src/plugins/builtin/treasury-daily/index.tsx +17 -0
  278. package/src/plugins/builtin/treasury-daily/model.ts +69 -0
  279. package/src/plugins/builtin/treasury-daily/pane.tsx +140 -0
  280. package/src/plugins/builtin/world-venue-map/entity-detail.tsx +15 -2
  281. package/src/plugins/builtin/world-venue-map/map.tsx +1 -0
  282. package/src/plugins/builtin-editorial.ts +1 -1
  283. package/src/plugins/catalog-browser.ts +25 -2
  284. package/src/plugins/marketplace/model.ts +57 -21
  285. package/src/renderers/dom/build-assets.ts +14 -5
  286. package/src/renderers/dom/data-table/index.tsx +5 -3
  287. package/src/renderers/dom/desktop/controls.tsx +2 -1
  288. package/src/renderers/dom/desktop/icons.tsx +25 -0
  289. package/src/renderers/dom/desktop/list-view.tsx +1 -1
  290. package/src/renderers/dom/desktop/menu.tsx +1 -1
  291. package/src/renderers/dom/desktop/query-bar.tsx +3 -1
  292. package/src/renderers/dom/host/chart-surface.tsx +7 -2
  293. package/src/renderers/dom/host/resize-rows.ts +111 -0
  294. package/src/renderers/dom/host/sticky-scroll.ts +22 -3
  295. package/src/renderers/dom/host/style.ts +14 -0
  296. package/src/renderers/dom/host/surface-3d.tsx +2 -1
  297. package/src/renderers/dom/host/surface-fit.ts +10 -6
  298. package/src/renderers/dom/host/text.tsx +2 -2
  299. package/src/renderers/dom/styles.css +63 -6
  300. package/src/renderers/electrobun/bun/desktop/app-badge.ts +37 -0
  301. package/src/renderers/electrobun/bun/desktop/backend.ts +1 -0
  302. package/src/renderers/electrobun/bun/desktop/host-requests.ts +8 -0
  303. package/src/renderers/electrobun/bun/desktop/macos-dock-badge.ts +37 -0
  304. package/src/renderers/electrobun/bun/desktop/macos-dock-icon.ts +2 -40
  305. package/src/renderers/electrobun/bun/desktop/macos-objc.ts +41 -0
  306. package/src/renderers/electrobun/bun/tui-entry.ts +18 -1
  307. package/src/renderers/electrobun/shared/protocol.ts +2 -0
  308. package/src/renderers/electrobun/view/app-badge-host.ts +17 -0
  309. package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +8 -3
  310. package/src/renderers/electrobun/view/main.tsx +2 -0
  311. package/src/renderers/electrobun/view/remote/asset-data-client.ts +5 -1
  312. package/src/series/validate.ts +1 -1
  313. package/src/shares/api.ts +5 -1
  314. package/src/shares/location.ts +31 -0
  315. package/src/shares/open.ts +26 -0
  316. package/src/shares/pane-image.ts +18 -6
  317. package/src/shares/personal-pane.ts +42 -54
  318. package/src/sources/gloomberb-cloud/index.ts +7 -2
  319. package/src/sources/gloomberb-cloud/normalizers.ts +5 -0
  320. package/src/sources/history-coverage.ts +22 -4
  321. package/src/sources/history-result.ts +3 -1
  322. package/src/sources/provider-errors.ts +2 -1
  323. package/src/sources/provider-router/batches.ts +18 -2
  324. package/src/sources/provider-router/index.ts +2 -1
  325. package/src/state/app/context/index.tsx +3 -2
  326. package/src/test-support/builtin-panes.ts +31 -0
  327. package/src/tickers/listing-venues.ts +22 -0
  328. package/src/tickers/search/index.ts +7 -2
  329. package/src/tickers/search/ranking.ts +19 -0
  330. package/src/time-series/chart-data.ts +2 -0
  331. package/src/time-series/parsed-history-cache.ts +41 -11
  332. package/src/time-series/resolve.ts +47 -15
  333. package/src/types/config.ts +1 -1
  334. package/src/types/data-provider.ts +13 -1
  335. package/src/types/financials.ts +13 -0
  336. package/src/types/headless.ts +22 -0
  337. package/src/types/plugin.ts +33 -6
  338. package/src/types/price-history.ts +2 -0
  339. package/src/ui/host.tsx +6 -0
  340. package/src/utils/crypto-pair.ts +1 -1
  341. package/src/utils/currency-pair.ts +66 -0
  342. package/src/utils/decimal-comma.ts +57 -0
  343. package/src/utils/guards.ts +25 -0
  344. package/src/utils/local-utc-offset.ts +37 -0
  345. package/src/utils/plugin-proxy-hosts.json +8 -1
  346. package/src/components/chart/composite/crosshair-readout.tsx +0 -150
  347. package/src/plugins/builtin/chat/message/ai-badge.tsx +0 -18
  348. package/src/plugins/builtin/credit-boards/pane.tsx +0 -30
@@ -163,6 +163,8 @@ export function missingPanePlaceholderDef(paneId: string): PaneDef {
163
163
  defaultMode: "floating",
164
164
  defaultFloatingSize: { width: 60, height: 12 },
165
165
  portableShare: { private: {} },
166
+ // It draws a notice, not the pane's own data.
167
+ personalData: () => null,
166
168
  };
167
169
  placeholders.set(paneId, def);
168
170
  }
@@ -513,6 +513,7 @@ export function Shell({
513
513
  const { canAsk, askAboutPane, askAboutFocusedPane } = useShellPaneAsk({
514
514
  focusedPaneId,
515
515
  getPaneTitle,
516
+ layout: visibleLayout,
516
517
  nativePaneChrome,
517
518
  paneMap,
518
519
  pluginRegistry,
@@ -1,4 +1,4 @@
1
- import { useCallback, useSyncExternalStore, type RefObject } from "react";
1
+ import { useCallback, useRef, useSyncExternalStore, type RefObject } from "react";
2
2
  import { buildAskGloomPaneAttachment } from "../../../../ask-gloom/pane-context";
3
3
  import {
4
4
  askGloomAboutPane,
@@ -9,13 +9,16 @@ import { domPaneText, terminalPaneText, type CellRect } from "../../../../ask-gl
9
9
  import type { DockLeafLayout, FloatingRect, LayoutBounds, ResolvedPane } from "../../../../layout/pane-manager";
10
10
  import type { PluginRegistry } from "../../../../plugins/registry";
11
11
  import { useRemoteUiRegistry, type RemoteUiRegistry } from "../../../../remote/semantic-tree";
12
- import { resolveTickerForPane, type AppState } from "../../../../state/app/context";
12
+ import type { AppState } from "../../../../state/app/context";
13
+ import type { LayoutConfig } from "../../../../types/config";
13
14
  import { useNativeRenderer } from "../../../../ui";
14
15
  import { readRenderableBounds } from "../cursor-occlusion";
15
16
 
16
17
  interface ShellPaneAskOptions {
17
18
  focusedPaneId: string | null;
18
19
  getPaneTitle: (pane: ResolvedPane) => string;
20
+ /** The layout the panes are in, for their `personalData` rules. */
21
+ layout: LayoutConfig;
19
22
  nativePaneChrome: boolean;
20
23
  paneMap: Map<string, ResolvedPane>;
21
24
  pluginRegistry: PluginRegistry;
@@ -68,6 +71,7 @@ function activePaneTabs(paneId: string, remoteUi: RemoteUiRegistry | null, nativ
68
71
  export function useShellPaneAsk({
69
72
  focusedPaneId,
70
73
  getPaneTitle,
74
+ layout,
71
75
  nativePaneChrome,
72
76
  paneMap,
73
77
  pluginRegistry,
@@ -79,6 +83,9 @@ export function useShellPaneAsk({
79
83
  const canAsk = useSyncExternalStore(subscribeAskGloomAboutPanes, canAskGloomAboutPanes, canAskGloomAboutPanes);
80
84
  const nativeRenderer = useNativeRenderer();
81
85
  const remoteUi = useRemoteUiRegistry();
86
+ // Read when asked, so a layout edit does not remake the actions that ask.
87
+ const layoutRef = useRef(layout);
88
+ layoutRef.current = layout;
82
89
 
83
90
  const readTerminalText = useCallback((paneId: string, cover: LayoutBounds | null | undefined): string | null => {
84
91
  const frame = nativeRenderer.captureFrame?.();
@@ -110,12 +117,10 @@ export function useShellPaneAsk({
110
117
  }
111
118
  const attachment = buildAskGloomPaneAttachment({
112
119
  registry: pluginRegistry,
113
- instance: pane.instance,
120
+ pane,
121
+ state,
122
+ layout: layoutRef.current,
114
123
  title: getPaneTitle(pane),
115
- symbol: resolveTickerForPane(state, paneId),
116
- paneState: state.paneState[paneId],
117
- config: state.config,
118
- tickers: state.tickers,
119
124
  activeTabs: activePaneTabs(paneId, remoteUi, nativePaneChrome),
120
125
  visibleText,
121
126
  });
@@ -1,18 +1,12 @@
1
1
  import { useCallback, useEffect, useRef, useState } from "react";
2
2
  import { createOneShot } from "../../../../utils/one-shot";
3
3
  import type { LayoutBounds, ResolvedPane } from "../../../../layout/pane-manager";
4
- import { getPaneSettings } from "../../../../pane-settings";
5
4
  import type { PluginRegistry } from "../../../../plugins/registry";
6
5
  import { paneScreenshotScale, PANE_SCREENSHOT_MIN_WIDTH } from "../../../../remote/pane-screenshot";
7
- import {
8
- base64Bytes,
9
- formatCaptureStamp,
10
- resolvePanePersonalData,
11
- type PaneImageCapture,
12
- } from "../../../../shares/pane-image";
13
- import { resolveCollectionForPane, resolveTickerForPane, useAppStateRef, type AppState } from "../../../../state/app/context";
6
+ import { base64Bytes, formatCaptureStamp, type PaneImageCapture } from "../../../../shares/pane-image";
7
+ import { panePersonalData } from "../../../../shares/personal-pane";
8
+ import { resolveTickerForPane, useAppStateRef } from "../../../../state/app/context";
14
9
  import type { LayoutConfig } from "../../../../types/config";
15
- import type { PanePersonalDataContext } from "../../../../types/plugin";
16
10
  import { useUiCapabilities, type NativeRendererHost } from "../../../../ui";
17
11
  import { buildPaneSharePayload } from "../../../../shares/pane";
18
12
  import { preparePaneShare } from "../../../../shares/prepare";
@@ -34,29 +28,6 @@ function nextFrames(count: number): Promise<void> {
34
28
  });
35
29
  }
36
30
 
37
- /** What a pane shows now, for its `personalData` rule. */
38
- function personalDataContext(state: AppState, layout: LayoutConfig, pane: ResolvedPane): PanePersonalDataContext {
39
- const paneId = pane.instance.instanceId;
40
- return {
41
- config: state.config,
42
- layout,
43
- paneId,
44
- paneType: pane.instance.paneId,
45
- pane: pane.instance,
46
- settings: getPaneSettings(pane.instance),
47
- paneState: state.paneState[paneId] ?? {},
48
- activeTicker: resolveTickerForPane(state, paneId),
49
- activeCollectionId: resolveCollectionForPane(state, paneId),
50
- tickers: state.tickers,
51
- };
52
- }
53
-
54
- /** Whether the plugin that owns a pane also connects a broker. */
55
- function ownerConnectsBroker(pluginRegistry: PluginRegistry, paneType: string): boolean {
56
- const owner = pluginRegistry.getPanePluginId(paneType);
57
- return !!owner && [...pluginRegistry.brokers.keys()].some((brokerType) => pluginRegistry.getBrokerPluginId(brokerType) === owner);
58
- }
59
-
60
31
  interface UseShellPaneCaptureOptions {
61
32
  appHeaderHeight: number;
62
33
  closePaneMenu: () => void;
@@ -135,8 +106,11 @@ export function useShellPaneCapture(options: UseShellPaneCaptureOptions): void {
135
106
  resolveTickerForPane(stateRef.current, paneId),
136
107
  stateRef.current.tickers,
137
108
  ) : null,
138
- personalData: resolvePanePersonalData(pane.def, personalDataContext(stateRef.current, current.layout, pane), {
139
- ownerConnectsBroker: ownerConnectsBroker(current.pluginRegistry, pane.def.id),
109
+ personalData: panePersonalData({
110
+ registry: current.pluginRegistry,
111
+ state: stateRef.current,
112
+ layout: current.layout,
113
+ pane,
140
114
  }),
141
115
  ...image,
142
116
  };
@@ -10,7 +10,13 @@ import { useUiCapabilities } from "../ui";
10
10
 
11
11
  export interface MarkdownTextProps {
12
12
  text: string;
13
+ /**
14
+ * Columns the terminal wraps at, and the width tables are fitted to. The
15
+ * desktop and the web wrap text at the width of the box it sits in.
16
+ */
13
17
  lineWidth?: number;
18
+ /** Desktop and web: the space a blank line leaves between paragraphs, in CSS units; one line when unset. */
19
+ paragraphGap?: string;
14
20
  catalog?: Record<string, InlineTickerCatalogEntry>;
15
21
  textColor?: string;
16
22
  openTicker?: (symbol: string) => void;
@@ -405,6 +411,21 @@ function wrappedTextStyle() {
405
411
  } as const;
406
412
  }
407
413
 
414
+ /**
415
+ * A wrapped line on the desktop and the web: a list item's later lines hang
416
+ * under its text rather than its marker, measured in characters of its own
417
+ * type.
418
+ */
419
+ function nativeLineStyle(parsed: ParsedLine) {
420
+ const marker = parsed.segments[0]?.text ?? "";
421
+ const hang = parsed.heading || !/^([-*]|\d+\.) $/.test(marker) ? 0 : (parsed.indent ?? 0) + marker.length;
422
+ return {
423
+ ...wrappedTextStyle(),
424
+ display: "block",
425
+ ...(hang > 0 ? { paddingLeft: `${hang}ch`, textIndent: `-${hang}ch` } : {}),
426
+ } as const;
427
+ }
428
+
408
429
  function wrappedInlineTextStyle() {
409
430
  return {
410
431
  ...wrappedTextStyle(),
@@ -412,6 +433,9 @@ function wrappedInlineTextStyle() {
412
433
  } as const;
413
434
  }
414
435
 
436
+ /** Desktop and web: the width of the box the text sits in, beside a list marker too. */
437
+ const NATIVE_FILL = { width: "100%", flexShrink: 1, minWidth: 0 } as const;
438
+
415
439
  function SegmentSpan({ segment, wrap = false, onOpenLink }: {
416
440
  segment: StyledSegment;
417
441
  wrap?: boolean;
@@ -479,15 +503,17 @@ function MarkdownLine({
479
503
  onHover: (symbol: string | null) => void;
480
504
  onOpenLink?: (href: string) => void;
481
505
  }) {
506
+ const { nativePaneChrome } = useUiCapabilities();
482
507
  const indent = parsed.indent ?? 0;
483
508
  const indentStr = indent > 0 ? " ".repeat(indent) : "";
484
- const shouldWrap = lineWidth != null;
509
+ // The desktop and the web always wrap, in CSS, across the box the text sits in.
510
+ const shouldWrap = lineWidth != null || nativePaneChrome === true;
485
511
  const textWrapProps = shouldWrap
486
512
  ? {
487
- width: lineWidth,
513
+ width: nativePaneChrome ? "100%" : lineWidth,
488
514
  wrapText: true,
489
515
  wrapMode: "word",
490
- style: wrappedTextStyle(),
516
+ style: nativePaneChrome ? nativeLineStyle(parsed) : wrappedTextStyle(),
491
517
  }
492
518
  : {};
493
519
 
@@ -511,7 +537,7 @@ function MarkdownLine({
511
537
  // Complex case: need to handle tickers within styled segments
512
538
  // Render as a flex row to allow badge elements
513
539
  return (
514
- <Box flexDirection="row" flexWrap="wrap" {...(lineWidth != null ? { width: lineWidth } : {})}>
540
+ <Box flexDirection="row" flexWrap="wrap" {...(nativePaneChrome ? NATIVE_FILL : lineWidth != null ? { width: lineWidth } : {})}>
515
541
  {indentStr ? <Text fg={textColor}>{indentStr}</Text> : null}
516
542
  {parsed.segments.map((segment, segIdx) => {
517
543
  const tokens = tokenizeTickerText(segment.text);
@@ -568,13 +594,16 @@ export function MarkdownText({
568
594
  textColor = colors.text,
569
595
  openTicker = () => {},
570
596
  onOpenLink,
597
+ paragraphGap,
571
598
  }: MarkdownTextProps) {
599
+ const { nativePaneChrome } = useUiCapabilities();
572
600
  const links = onOpenLink !== undefined;
573
601
  const [hoveredSymbol, setHoveredSymbol] = useState<string | null>(null);
574
602
  const blocks = parseMarkdownBlocks(text);
575
603
 
576
604
  return (
577
- <Box flexDirection="column" {...(lineWidth != null ? { width: lineWidth } : {})}>
605
+ // Rendered prose: the desktop and web let a person select and copy it.
606
+ <Box flexDirection="column" data-gloom-selectable="true" {...(nativePaneChrome ? NATIVE_FILL : lineWidth != null ? { width: lineWidth } : {})}>
578
607
  {blocks.map((block, index) => {
579
608
  if (block.kind === "table") {
580
609
  return (
@@ -591,7 +620,9 @@ export function MarkdownText({
591
620
  }
592
621
  const line = block.text;
593
622
  if (line.trim() === "") {
594
- return <Text key={index}>{" "}</Text>;
623
+ return nativePaneChrome && paragraphGap
624
+ ? <Box key={index} flexShrink={0} style={{ height: paragraphGap }} />
625
+ : <Text key={index}>{" "}</Text>;
595
626
  }
596
627
  const parsed = parseLine(line, links);
597
628
  return (