@newyorkcompute/kalshi-tui 0.1.0 → 0.3.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 (113) hide show
  1. package/README.md +35 -0
  2. package/dist/App.d.ts +2 -1
  3. package/dist/App.d.ts.map +1 -1
  4. package/dist/App.js +43 -36
  5. package/dist/App.js.map +1 -1
  6. package/dist/cache.d.ts +34 -0
  7. package/dist/cache.d.ts.map +1 -0
  8. package/dist/cache.js +60 -0
  9. package/dist/cache.js.map +1 -0
  10. package/dist/cache.test.d.ts +2 -0
  11. package/dist/cache.test.d.ts.map +1 -0
  12. package/dist/cache.test.js +73 -0
  13. package/dist/cache.test.js.map +1 -0
  14. package/dist/cli.d.ts +2 -2
  15. package/dist/cli.js +31 -35
  16. package/dist/cli.js.map +1 -1
  17. package/dist/components/ErrorBoundary.d.ts +20 -0
  18. package/dist/components/ErrorBoundary.d.ts.map +1 -0
  19. package/dist/components/ErrorBoundary.js +28 -0
  20. package/dist/components/ErrorBoundary.js.map +1 -0
  21. package/dist/components/Footer.d.ts +6 -0
  22. package/dist/components/Footer.d.ts.map +1 -0
  23. package/dist/components/Footer.js +10 -0
  24. package/dist/components/Footer.js.map +1 -0
  25. package/dist/components/Header.d.ts +10 -2
  26. package/dist/components/Header.d.ts.map +1 -1
  27. package/dist/components/Header.js +18 -9
  28. package/dist/components/Header.js.map +1 -1
  29. package/dist/components/Markets.d.ts +21 -0
  30. package/dist/components/Markets.d.ts.map +1 -0
  31. package/dist/components/Markets.js +25 -0
  32. package/dist/components/Markets.js.map +1 -0
  33. package/dist/components/Orderbook.d.ts +18 -5
  34. package/dist/components/Orderbook.d.ts.map +1 -1
  35. package/dist/components/Orderbook.js +25 -36
  36. package/dist/components/Orderbook.js.map +1 -1
  37. package/dist/components/Positions.d.ts +13 -2
  38. package/dist/components/Positions.d.ts.map +1 -1
  39. package/dist/components/Positions.js +10 -17
  40. package/dist/components/Positions.js.map +1 -1
  41. package/dist/components/PriceChart.d.ts +18 -0
  42. package/dist/components/PriceChart.d.ts.map +1 -0
  43. package/dist/components/PriceChart.js +103 -0
  44. package/dist/components/PriceChart.js.map +1 -0
  45. package/dist/components/index.d.ts +10 -10
  46. package/dist/components/index.d.ts.map +1 -1
  47. package/dist/components/index.js +10 -11
  48. package/dist/components/index.js.map +1 -1
  49. package/dist/hooks/index.d.ts +4 -4
  50. package/dist/hooks/index.d.ts.map +1 -1
  51. package/dist/hooks/index.js +4 -4
  52. package/dist/hooks/index.js.map +1 -1
  53. package/dist/hooks/useKalshi.d.ts +30 -12
  54. package/dist/hooks/useKalshi.d.ts.map +1 -1
  55. package/dist/hooks/useKalshi.js +249 -19
  56. package/dist/hooks/useKalshi.js.map +1 -1
  57. package/dist/utils.d.ts +33 -0
  58. package/dist/utils.d.ts.map +1 -0
  59. package/dist/utils.js +88 -0
  60. package/dist/utils.js.map +1 -0
  61. package/dist/utils.test.d.ts +2 -0
  62. package/dist/utils.test.d.ts.map +1 -0
  63. package/dist/utils.test.js +115 -0
  64. package/dist/utils.test.js.map +1 -0
  65. package/package.json +8 -8
  66. package/dist/components/HelpModal.d.ts +0 -5
  67. package/dist/components/HelpModal.d.ts.map +0 -1
  68. package/dist/components/HelpModal.js +0 -19
  69. package/dist/components/HelpModal.js.map +0 -1
  70. package/dist/components/MarketList.d.ts +0 -5
  71. package/dist/components/MarketList.d.ts.map +0 -1
  72. package/dist/components/MarketList.js +0 -68
  73. package/dist/components/MarketList.js.map +0 -1
  74. package/dist/components/OrderEntry.d.ts +0 -9
  75. package/dist/components/OrderEntry.d.ts.map +0 -1
  76. package/dist/components/OrderEntry.js +0 -77
  77. package/dist/components/OrderEntry.js.map +0 -1
  78. package/dist/components/SearchBar.d.ts +0 -5
  79. package/dist/components/SearchBar.d.ts.map +0 -1
  80. package/dist/components/SearchBar.js +0 -27
  81. package/dist/components/SearchBar.js.map +0 -1
  82. package/dist/components/StatusBar.d.ts +0 -5
  83. package/dist/components/StatusBar.d.ts.map +0 -1
  84. package/dist/components/StatusBar.js +0 -9
  85. package/dist/components/StatusBar.js.map +0 -1
  86. package/dist/components/ui/Box.d.ts +0 -14
  87. package/dist/components/ui/Box.d.ts.map +0 -1
  88. package/dist/components/ui/Box.js +0 -9
  89. package/dist/components/ui/Box.js.map +0 -1
  90. package/dist/components/ui/Sparkline.d.ts +0 -11
  91. package/dist/components/ui/Sparkline.d.ts.map +0 -1
  92. package/dist/components/ui/Sparkline.js +0 -32
  93. package/dist/components/ui/Sparkline.js.map +0 -1
  94. package/dist/hooks/useMarkets.d.ts +0 -13
  95. package/dist/hooks/useMarkets.d.ts.map +0 -1
  96. package/dist/hooks/useMarkets.js +0 -89
  97. package/dist/hooks/useMarkets.js.map +0 -1
  98. package/dist/hooks/useOrderbook.d.ts +0 -13
  99. package/dist/hooks/useOrderbook.d.ts.map +0 -1
  100. package/dist/hooks/useOrderbook.js +0 -81
  101. package/dist/hooks/useOrderbook.js.map +0 -1
  102. package/dist/hooks/usePortfolio.d.ts +0 -18
  103. package/dist/hooks/usePortfolio.d.ts.map +0 -1
  104. package/dist/hooks/usePortfolio.js +0 -84
  105. package/dist/hooks/usePortfolio.js.map +0 -1
  106. package/dist/stores/app-store.d.ts +0 -17
  107. package/dist/stores/app-store.d.ts.map +0 -1
  108. package/dist/stores/app-store.js +0 -21
  109. package/dist/stores/app-store.js.map +0 -1
  110. package/dist/theme.d.ts +0 -31
  111. package/dist/theme.d.ts.map +0 -1
  112. package/dist/theme.js +0 -37
  113. package/dist/theme.js.map +0 -1
package/README.md CHANGED
@@ -93,6 +93,41 @@ kalshi-tui
93
93
  3. Generate a new API key (you'll create an RSA key pair)
94
94
  4. Save your API Key ID and private key securely
95
95
 
96
+ ## Development
97
+
98
+ ```bash
99
+ # Install dependencies
100
+ npm install
101
+
102
+ # Build the TUI
103
+ npx nx run @newyorkcompute/kalshi-tui:build
104
+
105
+ # Run the TUI (loads .env.local)
106
+ npx dotenv -e .env.local -- node packages/tui/dist/cli.js
107
+ ```
108
+
109
+ ### Watch Mode
110
+
111
+ For active development, run the build in watch mode in one terminal:
112
+
113
+ ```bash
114
+ # Terminal 1: Watch for changes
115
+ npx nx run @newyorkcompute/kalshi-tui:dev
116
+ ```
117
+
118
+ Then run the TUI in another terminal:
119
+
120
+ ```bash
121
+ # Terminal 2: Run the app (re-run after changes compile)
122
+ npx dotenv -e .env.local -- node packages/tui/dist/cli.js
123
+ ```
124
+
125
+ ### Tech Stack
126
+
127
+ - **[Ink](https://github.com/vadimdemedes/ink)** - React for the terminal
128
+ - **[@inkjs/ui](https://github.com/vadimdemedes/ink-ui)** - Polished UI components
129
+ - **React 18** - Declarative UI with hooks
130
+
96
131
  ## Built By
97
132
 
98
133
  **New York Compute** — Command-native tools for quantitative research, execution, and market intelligence.
package/dist/App.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  /**
2
- * Main application component
2
+ * Kalshi TUI - Main Application
3
+ * Clean, minimal, beautiful terminal trading
3
4
  */
4
5
  export declare function App(): import("react/jsx-runtime").JSX.Element;
5
6
  //# sourceMappingURL=App.d.ts.map
package/dist/App.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../src/App.tsx"],"names":[],"mappings":"AAaA;;GAEG;AACH,wBAAgB,GAAG,4CA0FlB"}
1
+ {"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../src/App.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAYH,wBAAgB,GAAG,4CAwGlB"}
package/dist/App.js CHANGED
@@ -1,49 +1,56 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useEffect, useState } from "react";
3
- import { Box, Text, useApp, useInput } from "ink";
4
- import { Header } from "./components/Header.js";
5
- import { MarketList } from "./components/MarketList.js";
6
- import { Orderbook } from "./components/Orderbook.js";
7
- import { Positions } from "./components/Positions.js";
8
- import { OrderEntry } from "./components/OrderEntry.js";
9
- import { StatusBar } from "./components/StatusBar.js";
10
- import { HelpModal } from "./components/HelpModal.js";
11
- import { SearchBar } from "./components/SearchBar.js";
12
- import { useAppStore } from "./stores/app-store.js";
13
- import { useKalshi } from "./hooks/useKalshi.js";
14
2
  /**
15
- * Main application component
3
+ * Kalshi TUI - Main Application
4
+ * Clean, minimal, beautiful terminal trading
16
5
  */
6
+ import { Box, useApp, useInput, useStdout } from 'ink';
7
+ import { useState, useEffect } from 'react';
8
+ import { Header } from './components/Header.js';
9
+ import { Markets } from './components/Markets.js';
10
+ import { Orderbook } from './components/Orderbook.js';
11
+ import { Positions } from './components/Positions.js';
12
+ import { Footer } from './components/Footer.js';
13
+ import { PriceChart } from './components/PriceChart.js';
14
+ import { useKalshi } from './hooks/useKalshi.js';
17
15
  export function App() {
18
16
  const { exit } = useApp();
19
- const [error, setError] = useState(null);
20
- const { isConfigured, configError } = useKalshi();
21
- const selectedMarket = useAppStore((state) => state.selectedMarket);
17
+ const { stdout } = useStdout();
18
+ const [selectedIndex, setSelectedIndex] = useState(0);
19
+ // Get terminal dimensions
20
+ const width = stdout?.columns ?? 120;
21
+ const height = stdout?.rows ?? 40;
22
+ // Fetch data from Kalshi
23
+ const { markets, orderbook, balance, positions, isConnected, isRateLimited, error, selectMarket, priceHistory, } = useKalshi();
24
+ // Update orderbook when selection changes
25
+ useEffect(() => {
26
+ const ticker = markets[selectedIndex]?.ticker;
27
+ if (ticker) {
28
+ selectMarket(ticker);
29
+ }
30
+ }, [selectedIndex, markets, selectMarket]);
22
31
  // Handle keyboard input
23
32
  useInput((input, key) => {
24
- // Quit on 'q' or Ctrl+C
25
- if (input === "q" || (key.ctrl && input === "c")) {
33
+ if (input === 'q') {
26
34
  exit();
27
35
  }
28
- // Help on '?'
29
- if (input === "?") {
30
- useAppStore.getState().toggleHelp();
36
+ if (key.upArrow) {
37
+ setSelectedIndex(i => Math.max(0, i - 1));
31
38
  }
32
- });
33
- // Check configuration on mount
34
- useEffect(() => {
35
- if (configError) {
36
- setError(configError);
39
+ if (key.downArrow) {
40
+ setSelectedIndex(i => Math.min(markets.length - 1, i + 1));
37
41
  }
38
- }, [configError]);
39
- // Show error screen if not configured
40
- if (error) {
41
- return (_jsxs(Box, { flexDirection: "column", padding: 1, children: [_jsx(Box, { marginBottom: 1, children: _jsx(Text, { color: "red", bold: true, children: "Configuration Error" }) }), _jsx(Text, { color: "gray", children: error }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { color: "gray", children: "Set KALSHI_API_KEY and KALSHI_PRIVATE_KEY environment variables." }) }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { color: "gray", children: "Run `kalshi-tui --help` for more information." }) })] }));
42
- }
43
- // Loading state
44
- if (!isConfigured) {
45
- return (_jsxs(Box, { flexDirection: "column", padding: 1, children: [_jsx(Text, { color: "green", children: "\u2593" }), _jsx(Text, { children: " Connecting to Kalshi..." })] }));
46
- }
47
- return (_jsxs(Box, { flexDirection: "column", width: "100%", children: [_jsx(Header, {}), _jsx(SearchBar, {}), _jsxs(Box, { flexDirection: "row", flexGrow: 1, children: [_jsxs(Box, { flexDirection: "column", width: "50%", children: [_jsx(MarketList, {}), _jsx(Positions, {})] }), _jsxs(Box, { flexDirection: "column", width: "50%", children: [_jsx(Orderbook, { ticker: selectedMarket }), _jsx(OrderEntry, { ticker: selectedMarket })] })] }), _jsx(StatusBar, {}), _jsx(HelpModal, {})] }));
42
+ });
43
+ // Layout calculations
44
+ const leftWidth = Math.floor(width / 2);
45
+ const rightWidth = width - leftWidth;
46
+ const contentHeight = height - 6; // Header (3) + Footer (3)
47
+ const marketsHeight = Math.floor(contentHeight * 0.65);
48
+ const positionsHeight = contentHeight - marketsHeight;
49
+ // Right column split: Orderbook (top) + Chart (bottom)
50
+ const orderbookHeight = Math.floor(contentHeight * 0.55);
51
+ const chartHeight = contentHeight - orderbookHeight;
52
+ // Get selected market for orderbook/chart
53
+ const selectedMarket = markets[selectedIndex] ?? null;
54
+ return (_jsxs(Box, { flexDirection: "column", width: width, height: height, children: [_jsx(Header, { balance: balance, isConnected: isConnected, isRateLimited: isRateLimited, error: error }), _jsxs(Box, { flexDirection: "row", height: contentHeight, children: [_jsxs(Box, { flexDirection: "column", width: leftWidth, children: [_jsx(Markets, { markets: markets, selectedIndex: selectedIndex, height: marketsHeight }), _jsx(Positions, { positions: positions, height: positionsHeight })] }), _jsxs(Box, { flexDirection: "column", flexGrow: 1, children: [_jsx(Orderbook, { market: selectedMarket, orderbook: orderbook, height: orderbookHeight }), _jsx(PriceChart, { ticker: selectedMarket?.ticker ?? null, priceHistory: priceHistory, height: chartHeight, width: rightWidth })] })] }), _jsx(Footer, {})] }));
48
55
  }
49
56
  //# sourceMappingURL=App.js.map
package/dist/App.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"App.js","sourceRoot":"","sources":["../src/App.tsx"],"names":[],"mappings":";AAAA,OAAc,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACnD,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,CAAC;AAClD,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AACxD,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AACxD,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEjD;;GAEG;AACH,MAAM,UAAU,GAAG;IACjB,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,EAAE,CAAC;IAC1B,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAC;IACxD,MAAM,EAAE,YAAY,EAAE,WAAW,EAAE,GAAG,SAAS,EAAE,CAAC;IAClD,MAAM,cAAc,GAAG,WAAW,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;IAEpE,wBAAwB;IACxB,QAAQ,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;QACtB,wBAAwB;QACxB,IAAI,KAAK,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,IAAI,KAAK,KAAK,GAAG,CAAC,EAAE,CAAC;YACjD,IAAI,EAAE,CAAC;QACT,CAAC;QAED,cAAc;QACd,IAAI,KAAK,KAAK,GAAG,EAAE,CAAC;YAClB,WAAW,CAAC,QAAQ,EAAE,CAAC,UAAU,EAAE,CAAC;QACtC,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,+BAA+B;IAC/B,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,WAAW,EAAE,CAAC;YAChB,QAAQ,CAAC,WAAW,CAAC,CAAC;QACxB,CAAC;IACH,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC;IAElB,sCAAsC;IACtC,IAAI,KAAK,EAAE,CAAC;QACV,OAAO,CACL,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,OAAO,EAAE,CAAC,aACpC,KAAC,GAAG,IAAC,YAAY,EAAE,CAAC,YAClB,KAAC,IAAI,IAAC,KAAK,EAAC,KAAK,EAAC,IAAI,0CAEf,GACH,EACN,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,YAAE,KAAK,GAAQ,EACjC,KAAC,GAAG,IAAC,SAAS,EAAE,CAAC,YACf,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,iFAEX,GACH,EACN,KAAC,GAAG,IAAC,SAAS,EAAE,CAAC,YACf,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,8DAEX,GACH,IACF,CACP,CAAC;IACJ,CAAC;IAED,gBAAgB;IAChB,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,OAAO,CACL,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,OAAO,EAAE,CAAC,aACpC,KAAC,IAAI,IAAC,KAAK,EAAC,OAAO,uBAAS,EAC5B,KAAC,IAAI,2CAAgC,IACjC,CACP,CAAC;IACJ,CAAC;IAED,OAAO,CACL,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,KAAK,EAAC,MAAM,aAEtC,KAAC,MAAM,KAAG,EAGV,KAAC,SAAS,KAAG,EAGb,MAAC,GAAG,IAAC,aAAa,EAAC,KAAK,EAAC,QAAQ,EAAE,CAAC,aAElC,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,KAAK,EAAC,KAAK,aACrC,KAAC,UAAU,KAAG,EACd,KAAC,SAAS,KAAG,IACT,EAGN,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,KAAK,EAAC,KAAK,aACrC,KAAC,SAAS,IAAC,MAAM,EAAE,cAAc,GAAI,EACrC,KAAC,UAAU,IAAC,MAAM,EAAE,cAAc,GAAI,IAClC,IACF,EAGN,KAAC,SAAS,KAAG,EAGb,KAAC,SAAS,KAAG,IACT,CACP,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"App.js","sourceRoot":"","sources":["../src/App.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Simple TTL Cache
3
+ * Lightweight caching for API responses
4
+ */
5
+ /**
6
+ * Get cached data if not expired
7
+ */
8
+ export declare function getCached<T>(key: string, ttl?: number): T | null;
9
+ /**
10
+ * Set cached data with timestamp
11
+ */
12
+ export declare function setCache<T>(key: string, data: T): void;
13
+ /**
14
+ * Clear specific cache entry
15
+ */
16
+ export declare function clearCache(key: string): void;
17
+ /**
18
+ * Clear all cache entries
19
+ */
20
+ export declare function clearAllCache(): void;
21
+ /**
22
+ * Get cache stats (for debugging)
23
+ */
24
+ export declare function getCacheStats(): {
25
+ size: number;
26
+ keys: string[];
27
+ };
28
+ export declare const CACHE_TTL: {
29
+ readonly PRICE_HISTORY: number;
30
+ readonly MARKET_META: number;
31
+ readonly ORDERBOOK: 0;
32
+ readonly BALANCE: 0;
33
+ };
34
+ //# sourceMappingURL=cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAaH;;GAEG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,GAAE,MAAoB,GAAG,CAAC,GAAG,IAAI,CAY7E;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,GAAG,IAAI,CAKtD;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAE5C;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,IAAI,CAEpC;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAA;CAAE,CAKhE;AAGD,eAAO,MAAM,SAAS;;;;;CAKZ,CAAC"}
package/dist/cache.js ADDED
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Simple TTL Cache
3
+ * Lightweight caching for API responses
4
+ */
5
+ // Cache storage
6
+ const cache = new Map();
7
+ // Default TTL: 1 minute
8
+ const DEFAULT_TTL = 60 * 1000;
9
+ /**
10
+ * Get cached data if not expired
11
+ */
12
+ export function getCached(key, ttl = DEFAULT_TTL) {
13
+ const entry = cache.get(key);
14
+ if (!entry)
15
+ return null;
16
+ const isExpired = Date.now() - entry.timestamp > ttl;
17
+ if (isExpired) {
18
+ cache.delete(key);
19
+ return null;
20
+ }
21
+ return entry.data;
22
+ }
23
+ /**
24
+ * Set cached data with timestamp
25
+ */
26
+ export function setCache(key, data) {
27
+ cache.set(key, {
28
+ data,
29
+ timestamp: Date.now(),
30
+ });
31
+ }
32
+ /**
33
+ * Clear specific cache entry
34
+ */
35
+ export function clearCache(key) {
36
+ cache.delete(key);
37
+ }
38
+ /**
39
+ * Clear all cache entries
40
+ */
41
+ export function clearAllCache() {
42
+ cache.clear();
43
+ }
44
+ /**
45
+ * Get cache stats (for debugging)
46
+ */
47
+ export function getCacheStats() {
48
+ return {
49
+ size: cache.size,
50
+ keys: Array.from(cache.keys()),
51
+ };
52
+ }
53
+ // Cache TTL constants
54
+ export const CACHE_TTL = {
55
+ PRICE_HISTORY: 5 * 60 * 1000, // 5 minutes - trade history doesn't change rapidly
56
+ MARKET_META: 10 * 60 * 1000, // 10 minutes - titles/close times rarely change
57
+ ORDERBOOK: 0, // No cache - always fresh
58
+ BALANCE: 0, // No cache - always fresh
59
+ };
60
+ //# sourceMappingURL=cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.js","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,gBAAgB;AAChB,MAAM,KAAK,GAAG,IAAI,GAAG,EAA+B,CAAC;AAErD,wBAAwB;AACxB,MAAM,WAAW,GAAG,EAAE,GAAG,IAAI,CAAC;AAE9B;;GAEG;AACH,MAAM,UAAU,SAAS,CAAI,GAAW,EAAE,MAAc,WAAW;IACjE,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAE7B,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IAExB,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,SAAS,GAAG,GAAG,CAAC;IACrD,IAAI,SAAS,EAAE,CAAC;QACd,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAClB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,KAAK,CAAC,IAAS,CAAC;AACzB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,QAAQ,CAAI,GAAW,EAAE,IAAO;IAC9C,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE;QACb,IAAI;QACJ,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;KACtB,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,GAAW;IACpC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;AACpB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa;IAC3B,KAAK,CAAC,KAAK,EAAE,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa;IAC3B,OAAO;QACL,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;KAC/B,CAAC;AACJ,CAAC;AAED,sBAAsB;AACtB,MAAM,CAAC,MAAM,SAAS,GAAG;IACvB,aAAa,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,EAAG,mDAAmD;IAClF,WAAW,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI,EAAI,gDAAgD;IAC/E,SAAS,EAAE,CAAC,EAAoB,0BAA0B;IAC1D,OAAO,EAAE,CAAC,EAAsB,0BAA0B;CAClD,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=cache.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.test.d.ts","sourceRoot":"","sources":["../src/cache.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,73 @@
1
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
2
+ import { getCached, setCache, clearCache, clearAllCache, getCacheStats, } from './cache.js';
3
+ describe('cache', () => {
4
+ beforeEach(() => {
5
+ vi.useFakeTimers();
6
+ clearAllCache();
7
+ });
8
+ afterEach(() => {
9
+ vi.useRealTimers();
10
+ });
11
+ describe('setCache and getCached', () => {
12
+ it('stores and retrieves data', () => {
13
+ const data = { foo: 'bar' };
14
+ setCache('test-key', data);
15
+ const result = getCached('test-key');
16
+ expect(result).toEqual(data);
17
+ });
18
+ it('returns null for non-existent keys', () => {
19
+ const result = getCached('non-existent');
20
+ expect(result).toBeNull();
21
+ });
22
+ it('returns null for expired entries', () => {
23
+ setCache('test-key', { foo: 'bar' });
24
+ // Advance time past default TTL (60s)
25
+ vi.advanceTimersByTime(61 * 1000);
26
+ const result = getCached('test-key');
27
+ expect(result).toBeNull();
28
+ });
29
+ it('returns data within TTL', () => {
30
+ setCache('test-key', { foo: 'bar' });
31
+ // Advance time but stay within TTL
32
+ vi.advanceTimersByTime(30 * 1000);
33
+ const result = getCached('test-key');
34
+ expect(result).toEqual({ foo: 'bar' });
35
+ });
36
+ it('respects custom TTL', () => {
37
+ setCache('test-key', { foo: 'bar' });
38
+ // Custom TTL of 10 seconds
39
+ vi.advanceTimersByTime(11 * 1000);
40
+ const result = getCached('test-key', 10 * 1000);
41
+ expect(result).toBeNull();
42
+ });
43
+ });
44
+ describe('clearCache', () => {
45
+ it('clears specific entry', () => {
46
+ setCache('key1', 'value1');
47
+ setCache('key2', 'value2');
48
+ clearCache('key1');
49
+ expect(getCached('key1')).toBeNull();
50
+ expect(getCached('key2')).toBe('value2');
51
+ });
52
+ });
53
+ describe('clearAllCache', () => {
54
+ it('clears all entries', () => {
55
+ setCache('key1', 'value1');
56
+ setCache('key2', 'value2');
57
+ clearAllCache();
58
+ expect(getCached('key1')).toBeNull();
59
+ expect(getCached('key2')).toBeNull();
60
+ });
61
+ });
62
+ describe('getCacheStats', () => {
63
+ it('returns cache statistics', () => {
64
+ setCache('key1', 'value1');
65
+ setCache('key2', 'value2');
66
+ const stats = getCacheStats();
67
+ expect(stats.size).toBe(2);
68
+ expect(stats.keys).toContain('key1');
69
+ expect(stats.keys).toContain('key2');
70
+ });
71
+ });
72
+ });
73
+ //# sourceMappingURL=cache.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.test.js","sourceRoot":"","sources":["../src/cache.test.ts"],"names":[],"mappings":"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"}
package/dist/cli.d.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
3
  * Kalshi TUI - Terminal Trading Dashboard
4
+ * Built with Ink for buttery-smooth rendering
4
5
  *
5
- * A beautiful terminal interface for Kalshi prediction markets.
6
- * Built by New York Compute.
6
+ * Built by New York Compute
7
7
  */
8
8
  export {};
9
9
  //# sourceMappingURL=cli.d.ts.map
package/dist/cli.js CHANGED
@@ -1,10 +1,17 @@
1
1
  #!/usr/bin/env node
2
2
  import { jsx as _jsx } from "react/jsx-runtime";
3
- import { render } from "ink";
4
- import { App } from "./App.js";
3
+ /**
4
+ * Kalshi TUI - Terminal Trading Dashboard
5
+ * Built with Ink for buttery-smooth rendering
6
+ *
7
+ * Built by New York Compute
8
+ */
9
+ import { render } from 'ink';
10
+ import { App } from './App.js';
11
+ import { ErrorBoundary } from './components/ErrorBoundary.js';
5
12
  // Handle --help and --version flags
6
13
  const args = process.argv.slice(2);
7
- if (args.includes("--help") || args.includes("-h")) {
14
+ if (args.includes('--help') || args.includes('-h')) {
8
15
  console.log(`
9
16
  Kalshi TUI - Terminal Trading Dashboard
10
17
 
@@ -14,51 +21,40 @@ if (args.includes("--help") || args.includes("-h")) {
14
21
  Options:
15
22
  --help, -h Show this help message
16
23
  --version, -v Show version number
17
- --about Show about information
18
24
 
19
25
  Environment Variables:
20
26
  KALSHI_API_KEY Your Kalshi API key ID (required)
21
27
  KALSHI_PRIVATE_KEY RSA private key in PEM format (required)
22
- KALSHI_BASE_PATH API base URL (optional, defaults to production)
23
28
 
24
- Examples:
25
- $ kalshi-tui
26
- $ KALSHI_API_KEY=xxx KALSHI_PRIVATE_KEY="..." kalshi-tui
29
+ Controls:
30
+ ↑/↓ Navigate markets
31
+ q Quit
27
32
 
28
33
  Built by New York Compute
29
34
  https://newyorkcompute.xyz
30
35
  `);
31
36
  process.exit(0);
32
37
  }
33
- if (args.includes("--version") || args.includes("-v")) {
34
- console.log("0.1.0");
38
+ if (args.includes('--version') || args.includes('-v')) {
39
+ console.log('0.1.0');
35
40
  process.exit(0);
36
41
  }
37
- if (args.includes("--about")) {
38
- console.log(`
39
- ┌──────────────────────────────────────────────────────────┐
40
- │ │
41
- │ ▓ KALSHI TUI
42
- │ NEW YORK COMPUTE │
43
- │ │
44
- │ Free. Open source. Beautiful. │
45
- │ │
46
- │ A terminal so polished that the screenshot alone │
47
- │ is the pitch. No AI. No gimmicks. Pure craft. │
48
- │ │
49
- │ Version: 0.1.0 │
50
- │ License: MIT │
51
- │ │
52
- │ GitHub: github.com/newyorkcompute/kalshi │
53
- │ Website: newyorkcompute.xyz │
54
- │ │
55
- │ Want this for equities? Request early access: │
56
- │ → newyorkcompute.xyz │
57
- │ │
58
- └──────────────────────────────────────────────────────────┘
42
+ // Check if stdin supports raw mode (required for keyboard input)
43
+ const isRawModeSupported = process.stdin.isTTY;
44
+ if (!isRawModeSupported) {
45
+ console.error(`
46
+ Error: Kalshi TUI requires an interactive terminal.
47
+
48
+ This usually happens when running through a task runner or piped input.
49
+
50
+ Try running directly:
51
+ node dist/cli.js
52
+
53
+ Or:
54
+ npx @newyorkcompute/kalshi-tui
59
55
  `);
60
- process.exit(0);
56
+ process.exit(1);
61
57
  }
62
- // Render the app
63
- render(_jsx(App, {}));
58
+ // Render the app with error boundary
59
+ render(_jsx(ErrorBoundary, { children: _jsx(App, {}) }));
64
60
  //# sourceMappingURL=cli.js.map
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.tsx"],"names":[],"mappings":";;AASA,OAAO,EAAE,MAAM,EAAE,MAAM,KAAK,CAAC;AAC7B,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAE/B,oCAAoC;AACpC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAEnC,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;IACnD,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;;;CAsBb,CAAC,CAAC;IACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,IAAI,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;IACtD,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACrB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,IAAI,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;IAC7B,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;;CAqBb,CAAC,CAAC;IACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,iBAAiB;AACjB,MAAM,CAAC,KAAC,GAAG,KAAG,CAAC,CAAC"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.tsx"],"names":[],"mappings":";;AACA;;;;;GAKG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,KAAK,CAAC;AAC7B,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAC/B,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAE9D,oCAAoC;AACpC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAEnC,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;IACnD,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;CAoBb,CAAC,CAAC;IACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,IAAI,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;IACtD,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACrB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,iEAAiE;AACjE,MAAM,kBAAkB,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC;AAE/C,IAAI,CAAC,kBAAkB,EAAE,CAAC;IACxB,OAAO,CAAC,KAAK,CAAC;;;;;;;;;;CAUf,CAAC,CAAC;IACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,qCAAqC;AACrC,MAAM,CACJ,KAAC,aAAa,cACZ,KAAC,GAAG,KAAG,GACO,CACjB,CAAC"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Error Boundary Component
3
+ * Catches unhandled errors and displays a user-friendly message
4
+ */
5
+ import React, { Component, ReactNode } from 'react';
6
+ interface Props {
7
+ children: ReactNode;
8
+ }
9
+ interface State {
10
+ hasError: boolean;
11
+ error?: Error;
12
+ }
13
+ export declare class ErrorBoundary extends Component<Props, State> {
14
+ constructor(props: Props);
15
+ static getDerivedStateFromError(error: Error): State;
16
+ componentDidCatch(error: Error, errorInfo: React.ErrorInfo): void;
17
+ render(): string | number | boolean | import("react/jsx-runtime").JSX.Element | Iterable<React.ReactNode> | null | undefined;
18
+ }
19
+ export {};
20
+ //# sourceMappingURL=ErrorBoundary.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ErrorBoundary.d.ts","sourceRoot":"","sources":["../../src/components/ErrorBoundary.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGpD,UAAU,KAAK;IACb,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,UAAU,KAAK;IACb,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,KAAK,CAAC;CACf;AAED,qBAAa,aAAc,SAAQ,SAAS,CAAC,KAAK,EAAE,KAAK,CAAC;gBAC5C,KAAK,EAAE,KAAK;IAKxB,MAAM,CAAC,wBAAwB,CAAC,KAAK,EAAE,KAAK,GAAG,KAAK;IAIpD,iBAAiB,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS;IAM1D,MAAM;CA+CP"}
@@ -0,0 +1,28 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * Error Boundary Component
4
+ * Catches unhandled errors and displays a user-friendly message
5
+ */
6
+ import { Component } from 'react';
7
+ import { Box, Text } from 'ink';
8
+ export class ErrorBoundary extends Component {
9
+ constructor(props) {
10
+ super(props);
11
+ this.state = { hasError: false };
12
+ }
13
+ static getDerivedStateFromError(error) {
14
+ return { hasError: true, error };
15
+ }
16
+ componentDidCatch(error, errorInfo) {
17
+ // Log error for debugging
18
+ console.error('TUI Error:', error);
19
+ console.error('Component Stack:', errorInfo.componentStack);
20
+ }
21
+ render() {
22
+ if (this.state.hasError) {
23
+ return (_jsxs(Box, { flexDirection: "column", padding: 2, children: [_jsx(Box, { marginBottom: 1, children: _jsx(Text, { color: "red", bold: true, children: "\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557" }) }), _jsx(Box, { children: _jsx(Text, { color: "red", bold: true, children: "\u2551 \u26A0\uFE0F FATAL ERROR \u2551" }) }), _jsx(Box, { marginBottom: 1, children: _jsx(Text, { color: "red", bold: true, children: "\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D" }) }), _jsx(Box, { marginBottom: 1, children: _jsx(Text, { color: "gray", children: "Something went wrong:" }) }), _jsx(Box, { marginBottom: 1, children: _jsx(Text, { color: "yellow", wrap: "wrap", children: this.state.error?.message || 'Unknown error' }) }), _jsxs(Box, { marginTop: 1, children: [_jsx(Text, { color: "gray", children: "Press " }), _jsx(Text, { color: "cyan", bold: true, children: "Ctrl+C" }), _jsx(Text, { color: "gray", children: " to exit" })] }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { color: "gray", dimColor: true, children: "If this persists, please report at github.com/newyorkcompute/kalshi/issues" }) })] }));
24
+ }
25
+ return this.props.children;
26
+ }
27
+ }
28
+ //# sourceMappingURL=ErrorBoundary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ErrorBoundary.js","sourceRoot":"","sources":["../../src/components/ErrorBoundary.tsx"],"names":[],"mappings":";AAAA;;;GAGG;AAEH,OAAc,EAAE,SAAS,EAAa,MAAM,OAAO,CAAC;AACpD,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAWhC,MAAM,OAAO,aAAc,SAAQ,SAAuB;IACxD,YAAY,KAAY;QACtB,KAAK,CAAC,KAAK,CAAC,CAAC;QACb,IAAI,CAAC,KAAK,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;IACnC,CAAC;IAED,MAAM,CAAC,wBAAwB,CAAC,KAAY;QAC1C,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;IACnC,CAAC;IAED,iBAAiB,CAAC,KAAY,EAAE,SAA0B;QACxD,0BAA0B;QAC1B,OAAO,CAAC,KAAK,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;QACnC,OAAO,CAAC,KAAK,CAAC,kBAAkB,EAAE,SAAS,CAAC,cAAc,CAAC,CAAC;IAC9D,CAAC;IAED,MAAM;QACJ,IAAI,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;YACxB,OAAO,CACL,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,OAAO,EAAE,CAAC,aACpC,KAAC,GAAG,IAAC,YAAY,EAAE,CAAC,YAClB,KAAC,IAAI,IAAC,KAAK,EAAC,KAAK,EAAC,IAAI,+RAEf,GACH,EACN,KAAC,GAAG,cACF,KAAC,IAAI,IAAC,KAAK,EAAC,KAAK,EAAC,IAAI,uFAEf,GACH,EACN,KAAC,GAAG,IAAC,YAAY,EAAE,CAAC,YAClB,KAAC,IAAI,IAAC,KAAK,EAAC,KAAK,EAAC,IAAI,+RAEf,GACH,EAEN,KAAC,GAAG,IAAC,YAAY,EAAE,CAAC,YAClB,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,sCAA6B,GAC3C,EAEN,KAAC,GAAG,IAAC,YAAY,EAAE,CAAC,YAClB,KAAC,IAAI,IAAC,KAAK,EAAC,QAAQ,EAAC,IAAI,EAAC,MAAM,YAC7B,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,OAAO,IAAI,eAAe,GACxC,GACH,EAEN,MAAC,GAAG,IAAC,SAAS,EAAE,CAAC,aACf,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,uBAAc,EAChC,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,EAAC,IAAI,6BAAc,EACrC,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,yBAAgB,IAC9B,EAEN,KAAC,GAAG,IAAC,SAAS,EAAE,CAAC,YACf,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,EAAC,QAAQ,iGAEpB,GACH,IACF,CACP,CAAC;QACJ,CAAC;QAED,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC;IAC7B,CAAC;CACF"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Footer Component
3
+ * Branding and keyboard shortcuts
4
+ */
5
+ export declare function Footer(): import("react/jsx-runtime").JSX.Element;
6
+ //# sourceMappingURL=Footer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Footer.d.ts","sourceRoot":"","sources":["../../src/components/Footer.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,wBAAgB,MAAM,4CAiBrB"}
@@ -0,0 +1,10 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * Footer Component
4
+ * Branding and keyboard shortcuts
5
+ */
6
+ import { Box, Text } from 'ink';
7
+ export function Footer() {
8
+ return (_jsxs(Box, { flexDirection: "row", justifyContent: "space-between", borderStyle: "single", borderColor: "gray", paddingX: 1, height: 3, width: "100%", children: [_jsxs(Text, { children: ["Built by ", _jsx(Text, { bold: true, children: "New York Compute" }), " \u2022 ", _jsx(Text, { color: "green", children: "newyorkcompute.xyz" })] }), _jsx(Text, { color: "gray", children: "[\u2191\u2193] Navigate [q] Quit" })] }));
9
+ }
10
+ //# sourceMappingURL=Footer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Footer.js","sourceRoot":"","sources":["../../src/components/Footer.tsx"],"names":[],"mappings":";AAAA;;;GAGG;AAEH,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAEhC,MAAM,UAAU,MAAM;IACpB,OAAO,CACL,MAAC,GAAG,IACF,aAAa,EAAC,KAAK,EACnB,cAAc,EAAC,eAAe,EAC9B,WAAW,EAAC,QAAQ,EACpB,WAAW,EAAC,MAAM,EAClB,QAAQ,EAAE,CAAC,EACX,MAAM,EAAE,CAAC,EACT,KAAK,EAAC,MAAM,aAEZ,MAAC,IAAI,4BACM,KAAC,IAAI,IAAC,IAAI,uCAAwB,cAAG,KAAC,IAAI,IAAC,KAAK,EAAC,OAAO,mCAA0B,IACtF,EACP,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,iDAA8B,IAC5C,CACP,CAAC;AACJ,CAAC"}
@@ -1,5 +1,13 @@
1
1
  /**
2
- * Header component with branding and balance
2
+ * Header Component
3
+ * Displays branding, balance, and connection status
3
4
  */
4
- export declare function Header(): import("react/jsx-runtime").JSX.Element;
5
+ interface HeaderProps {
6
+ balance: number | null;
7
+ isConnected: boolean;
8
+ isRateLimited?: boolean;
9
+ error: string | null;
10
+ }
11
+ export declare function Header({ balance, isConnected, isRateLimited, error }: HeaderProps): import("react/jsx-runtime").JSX.Element;
12
+ export {};
5
13
  //# sourceMappingURL=Header.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Header.d.ts","sourceRoot":"","sources":["../../src/components/Header.tsx"],"names":[],"mappings":"AAMA;;GAEG;AACH,wBAAgB,MAAM,4CA4CrB"}
1
+ {"version":3,"file":"Header.d.ts","sourceRoot":"","sources":["../../src/components/Header.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,UAAU,WAAW;IACnB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,WAAW,EAAE,OAAO,CAAC;IACrB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAED,wBAAgB,MAAM,CAAC,EAAE,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,KAAK,EAAE,EAAE,WAAW,2CAkDjF"}