gloomberb 0.7.2 → 0.7.3

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 (129) hide show
  1. package/README.md +79 -132
  2. package/package.json +1 -1
  3. package/src/app.tsx +73 -67
  4. package/src/components/chart/chart-data.ts +7 -2
  5. package/src/components/chart/chart-pane-settings.ts +7 -4
  6. package/src/components/chart/chart-renderer.ts +49 -15
  7. package/src/components/chart/chart-types.ts +2 -2
  8. package/src/components/chart/chart.test.ts +27 -8
  9. package/src/components/chart/comparison-stock-chart.tsx +84 -121
  10. package/src/components/chart/native/chart-rasterizer.ts +43 -17
  11. package/src/components/chart/price-axis-labels.tsx +25 -9
  12. package/src/components/chart/stock-chart-renderer-switch.test.tsx +1 -1
  13. package/src/components/chart/stock-chart.tsx +59 -41
  14. package/src/components/command-bar/command-bar.test.tsx +446 -120
  15. package/src/components/command-bar/command-bar.tsx +528 -383
  16. package/src/components/command-bar/command-registry.ts +16 -6
  17. package/src/components/command-bar/root-shortcuts.ts +4 -5
  18. package/src/components/command-bar/view-model.test.ts +1 -0
  19. package/src/components/command-bar/view-model.ts +2 -1
  20. package/src/components/command-bar/workflow-ops.ts +11 -32
  21. package/src/components/data-table-view.test.tsx +24 -1
  22. package/src/components/data-table-view.tsx +3 -2
  23. package/src/components/feed-data-table-stack-view.tsx +3 -2
  24. package/src/components/layout/detached-pane-shell.tsx +2 -2
  25. package/src/components/layout/floating-pane.tsx +9 -2
  26. package/src/components/layout/pane-footer.tsx +1 -1
  27. package/src/components/layout/pane-header.tsx +4 -2
  28. package/src/components/layout/pane-sizing.ts +12 -0
  29. package/src/components/layout/pane.tsx +24 -2
  30. package/src/components/layout/shell.tsx +24 -10
  31. package/src/components/layout/status-bar.test.tsx +4 -1
  32. package/src/components/layout/status-bar.tsx +4 -24
  33. package/src/components/markdown-text.tsx +53 -8
  34. package/src/components/onboarding/onboarding-wizard.tsx +7 -6
  35. package/src/components/pane-settings-dialog.tsx +9 -6
  36. package/src/components/pane-template-wizard.tsx +3 -2
  37. package/src/components/price-selector-dialog.tsx +3 -2
  38. package/src/components/price-sparkline-view.tsx +463 -0
  39. package/src/components/price-sparkline.ts +46 -0
  40. package/src/components/table-view-shared.tsx +21 -3
  41. package/src/components/ticker-list-table-view.tsx +3 -2
  42. package/src/components/ticker-list-table.tsx +11 -51
  43. package/src/components/toggle-list.tsx +3 -3
  44. package/src/components/ui/choice-dialog.tsx +3 -2
  45. package/src/components/ui/multi-select-dialog.tsx +3 -2
  46. package/src/components/ui/native-select.tsx +3 -3
  47. package/src/core/state/app-state.ts +210 -80
  48. package/src/data/config-store-node.ts +113 -25
  49. package/src/data/config-store.test.ts +65 -3
  50. package/src/data/plugin-state-store.ts +39 -13
  51. package/src/data/sqlite-cache.test.ts +13 -0
  52. package/src/market-data/coordinator.ts +8 -1
  53. package/src/news/aggregator.test.ts +41 -0
  54. package/src/news/aggregator.ts +61 -9
  55. package/src/plugins/builtin/ai/ask-ai-detail-tab.tsx +25 -6
  56. package/src/plugins/builtin/ai/settings.ts +3 -0
  57. package/src/plugins/builtin/broker-manager/index.tsx +4 -3
  58. package/src/plugins/builtin/chat-controller.test.ts +398 -17
  59. package/src/plugins/builtin/chat-controller.ts +258 -44
  60. package/src/plugins/builtin/chat.test.tsx +257 -6
  61. package/src/plugins/builtin/chat.tsx +225 -60
  62. package/src/plugins/builtin/comparison-chart.test.tsx +117 -3
  63. package/src/plugins/builtin/correlation/colors.test.ts +39 -0
  64. package/src/plugins/builtin/correlation/colors.ts +87 -0
  65. package/src/plugins/builtin/correlation/index.test.tsx +151 -0
  66. package/src/plugins/builtin/correlation/index.tsx +92 -21
  67. package/src/plugins/builtin/debug.tsx +4 -3
  68. package/src/plugins/builtin/econ/index.tsx +3 -2
  69. package/src/plugins/builtin/help.test.tsx +2 -2
  70. package/src/plugins/builtin/holders/index.tsx +25 -13
  71. package/src/plugins/builtin/layout-manager.tsx +1 -7
  72. package/src/plugins/builtin/news-wire/index.tsx +1 -1
  73. package/src/plugins/builtin/news-wire/news-detail-view.tsx +3 -2
  74. package/src/plugins/builtin/news-wire/news-preset-pane.tsx +4 -1
  75. package/src/plugins/builtin/news-wire/persisted-articles.ts +7 -1
  76. package/src/plugins/builtin/options.tsx +9 -17
  77. package/src/plugins/builtin/portfolio-list/cli/commands.ts +6 -10
  78. package/src/plugins/builtin/portfolio-list/metrics.ts +11 -0
  79. package/src/plugins/builtin/portfolio-list/mutations.ts +17 -0
  80. package/src/plugins/builtin/portfolio-list/pane.tsx +117 -18
  81. package/src/plugins/builtin/portfolio-list/quick-add.tsx +422 -0
  82. package/src/plugins/builtin/portfolio-list/settings.ts +20 -12
  83. package/src/plugins/builtin/portfolio-list/table.tsx +3 -3
  84. package/src/plugins/builtin/portfolio-list.test.tsx +282 -2
  85. package/src/plugins/builtin/quote-monitor.test.tsx +158 -25
  86. package/src/plugins/builtin/sectors/index.tsx +252 -41
  87. package/src/plugins/builtin/sectors/sector-data.ts +41 -1
  88. package/src/plugins/builtin/ticker-detail/chart-tab.tsx +3 -2
  89. package/src/plugins/builtin/ticker-detail/index.tsx +30 -9
  90. package/src/plugins/builtin/ticker-detail/overview-tab.tsx +25 -15
  91. package/src/plugins/builtin/ticker-detail/pane.tsx +0 -6
  92. package/src/plugins/builtin/ticker-detail/quote-monitor.tsx +442 -63
  93. package/src/plugins/builtin/ticker-detail/settings.ts +84 -3
  94. package/src/plugins/builtin/ticker-detail.test.tsx +2 -2
  95. package/src/plugins/ibkr/trading-pane.tsx +3 -2
  96. package/src/plugins/plugin-runtime.tsx +2 -2
  97. package/src/plugins/prediction-markets/settings.ts +4 -0
  98. package/src/plugins/registry.test.ts +55 -0
  99. package/src/plugins/registry.ts +11 -4
  100. package/src/plugins/ticker-navigation.test.ts +35 -5
  101. package/src/plugins/ticker-navigation.ts +16 -22
  102. package/src/renderers/electrobun/bun/application-menu-click.test.ts +9 -0
  103. package/src/renderers/electrobun/bun/application-menu-click.ts +7 -4
  104. package/src/renderers/electrobun/bun/application-menu.ts +6 -1
  105. package/src/renderers/electrobun/bun/desktop-workspace.ts +47 -29
  106. package/src/renderers/electrobun/bun/index.ts +52 -13
  107. package/src/renderers/electrobun/view/app-services.ts +51 -9
  108. package/src/renderers/electrobun/view/backend-rpc.ts +5 -8
  109. package/src/renderers/electrobun/view/desktop-controls.tsx +4 -4
  110. package/src/renderers/electrobun/view/main.tsx +0 -16
  111. package/src/renderers/electrobun/view/styles.css +23 -21
  112. package/src/renderers/electrobun/view/ui-host.tsx +6 -4
  113. package/src/renderers/opentui/host.tsx +2 -1
  114. package/src/renderers/opentui/start.tsx +1 -1
  115. package/src/renderers/opentui/test-utils.tsx +6 -5
  116. package/src/state/app-bootstrap.ts +3 -3
  117. package/src/state/app-context.test.ts +113 -0
  118. package/src/state/app-context.tsx +8 -4
  119. package/src/theme/colors.ts +13 -14
  120. package/src/types/config.ts +9 -4
  121. package/src/types/plugin.ts +8 -1
  122. package/src/ui/context-menu.tsx +4 -4
  123. package/src/utils/api-client.test.ts +128 -0
  124. package/src/utils/api-client.ts +112 -7
  125. package/src/utils/fuzzy-search.ts +12 -1
  126. package/src/utils/keyboard.ts +31 -0
  127. package/src/utils/ticker-search.test.ts +2 -2
  128. package/src/utils/ticker-search.ts +48 -1
  129. package/src/version.ts +1 -1
@@ -0,0 +1,31 @@
1
+ export interface KeyboardModifierEventLike {
2
+ ctrl?: boolean;
3
+ meta?: boolean;
4
+ super?: boolean;
5
+ alt?: boolean;
6
+ option?: boolean;
7
+ shift?: boolean;
8
+ name?: string;
9
+ }
10
+
11
+ export function hasKeyboardModifier(event: KeyboardModifierEventLike): boolean {
12
+ return !!(
13
+ event.ctrl
14
+ || event.meta
15
+ || event.super
16
+ || event.alt
17
+ || event.option
18
+ || event.shift
19
+ );
20
+ }
21
+
22
+ export function isPlainKeyboardEvent(event: KeyboardModifierEventLike): boolean {
23
+ return !hasKeyboardModifier(event);
24
+ }
25
+
26
+ export function isPlainKey(
27
+ event: KeyboardModifierEventLike,
28
+ ...names: string[]
29
+ ): boolean {
30
+ return isPlainKeyboardEvent(event) && names.includes(event.name ?? "");
31
+ }
@@ -82,7 +82,7 @@ describe("ticker-search utilities", () => {
82
82
  ]),
83
83
  });
84
84
 
85
- expect(results.map((item) => item.id)).toEqual(["goto:AAPL", "search:APP"]);
85
+ expect(results.map((item) => item.id)).toEqual(["goto:AAPL", "search:APP:NASDAQ:TEST"]);
86
86
  expect(findExactTickerSearchMatch(results, "AAPL")?.id).toBe("goto:AAPL");
87
87
  });
88
88
 
@@ -97,7 +97,7 @@ describe("ticker-search utilities", () => {
97
97
  ]),
98
98
  });
99
99
 
100
- expect(results.map((item) => item.id)).toEqual(["goto:AAPL", "search:APLE"]);
100
+ expect(results.map((item) => item.id)).toEqual(["goto:AAPL", "search:APLE:NASDAQ:TEST"]);
101
101
  expect(results[0]).toMatchObject({
102
102
  id: "goto:AAPL",
103
103
  detail: "Apple Inc",
@@ -140,7 +140,7 @@ export function createProviderTickerSearchCandidates(
140
140
  const symbol = getSearchResultSymbol(result);
141
141
  const saved = localTickers.has(symbol);
142
142
  return [{
143
- id: `search:${result.symbol}`,
143
+ id: buildProviderCandidateId(result, symbol),
144
144
  label: symbol,
145
145
  symbol,
146
146
  detail: [result.name, result.brokerLabel, result.type].filter(Boolean).join(" | "),
@@ -357,6 +357,7 @@ export function rankTickerSearchItems<T extends Pick<TickerSearchRankableItem, "
357
357
  item,
358
358
  index,
359
359
  normalizedSymbol: normalizeSearchText(item.symbol || item.label),
360
+ symbolMatchRank: scoreSymbolMatchRank(intent, item),
360
361
  textScore,
361
362
  score: textScore + priorityScore + (textScore > 0 && saved ? 900 : 0),
362
363
  };
@@ -375,6 +376,7 @@ export function rankTickerSearchItems<T extends Pick<TickerSearchRankableItem, "
375
376
  return !matchedLocalSymbols.has(normalizedSymbol);
376
377
  })
377
378
  .sort((a, b) => {
379
+ if (b.symbolMatchRank !== a.symbolMatchRank) return b.symbolMatchRank - a.symbolMatchRank;
378
380
  if (b.score !== a.score) return b.score - a.score;
379
381
  const aSaved = isSavedSearchItem(a.item);
380
382
  const bSaved = isSavedSearchItem(b.item);
@@ -463,6 +465,16 @@ function buildProviderSearchResultKey(result: InstrumentSearchResult): string {
463
465
  ].join("|");
464
466
  }
465
467
 
468
+ function buildProviderCandidateId(result: InstrumentSearchResult, symbol: string): string {
469
+ return [
470
+ "search",
471
+ normalizeTickerSymbol(symbol),
472
+ normalizeSearchText(result.exchange || result.primaryExchange || result.type || ""),
473
+ normalizeSearchText(result.currency || ""),
474
+ normalizeSearchText(result.providerId || ""),
475
+ ].filter(Boolean).join(":");
476
+ }
477
+
466
478
  function getProviderHintRichness(result: InstrumentSearchResult): number {
467
479
  let score = 0;
468
480
  if (result.name) score += Math.min(120, result.name.length);
@@ -728,6 +740,41 @@ function scoreSearchAlias(intent: SearchQueryIntent, alias: string): number {
728
740
  return score;
729
741
  }
730
742
 
743
+ function scoreSymbolMatchRank(
744
+ intent: SearchQueryIntent,
745
+ item: Pick<TickerSearchRankableItem, "label"> & Partial<TickerSearchRankableItem>,
746
+ ): number {
747
+ if (!intent.normalizedQuery && !intent.compactQuery) return 0;
748
+ const displaySymbol = normalizeSearchText(item.symbol || item.label);
749
+ const compactDisplaySymbol = compactSearchText(item.symbol || item.label);
750
+
751
+ if (
752
+ displaySymbol === intent.normalizedQuery
753
+ || (intent.compactQuery && compactDisplaySymbol === intent.compactQuery)
754
+ ) {
755
+ return 3;
756
+ }
757
+
758
+ const aliases = getItemSearchAliases(item);
759
+ if (aliases.some((alias) => {
760
+ const normalizedAlias = normalizeSearchText(alias);
761
+ const compactAlias = compactSearchText(alias);
762
+ return normalizedAlias === intent.normalizedQuery
763
+ || (intent.compactQuery && compactAlias === intent.compactQuery);
764
+ })) {
765
+ return 2;
766
+ }
767
+
768
+ if (
769
+ displaySymbol.startsWith(intent.normalizedQuery)
770
+ || (intent.compactQuery && compactDisplaySymbol.startsWith(intent.compactQuery))
771
+ ) {
772
+ return 1;
773
+ }
774
+
775
+ return 0;
776
+ }
777
+
731
778
  function scoreAssetPreference(intent: SearchQueryIntent, instrumentClass?: TickerSearchInstrumentClass): number {
732
779
  const itemClass = instrumentClass || "other";
733
780
  if (!intent.assetPreference) {
package/src/version.ts CHANGED
@@ -1 +1 @@
1
- export const VERSION = "0.7.2";
1
+ export const VERSION = "0.7.3";