@aiaiaichain/agent 0.1.1

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 (68) hide show
  1. package/README.md +157 -0
  2. package/bin/aiai-mcp +31 -0
  3. package/bin/aiaiaicli +60 -0
  4. package/dist/api/ExtensionAPI.d.ts +68 -0
  5. package/dist/api/ExtensionAPI.js +9 -0
  6. package/dist/api/Registry.d.ts +24 -0
  7. package/dist/api/Registry.js +58 -0
  8. package/dist/cli.d.ts +6 -0
  9. package/dist/cli.js +252 -0
  10. package/dist/core/AgentDir.d.ts +10 -0
  11. package/dist/core/AgentDir.js +74 -0
  12. package/dist/core/ChainConfig.d.ts +19 -0
  13. package/dist/core/ChainConfig.js +65 -0
  14. package/dist/core/EnvLoader.d.ts +15 -0
  15. package/dist/core/EnvLoader.js +58 -0
  16. package/dist/index.d.ts +41 -0
  17. package/dist/index.js +42 -0
  18. package/dist/loader.d.ts +11 -0
  19. package/dist/loader.js +73 -0
  20. package/dist/mcp/entry.d.ts +5 -0
  21. package/dist/mcp/entry.js +10 -0
  22. package/dist/mcp/server.d.ts +14 -0
  23. package/dist/mcp/server.js +137 -0
  24. package/dist/models/CostTracker.d.ts +38 -0
  25. package/dist/models/CostTracker.js +75 -0
  26. package/dist/models/ModelRegistry.d.ts +70 -0
  27. package/dist/models/ModelRegistry.js +163 -0
  28. package/dist/runner/AgentRunner.d.ts +54 -0
  29. package/dist/runner/AgentRunner.js +171 -0
  30. package/dist/runner/ModelClient.d.ts +30 -0
  31. package/dist/runner/ModelClient.js +84 -0
  32. package/dist/runner/SwarmRouter.d.ts +23 -0
  33. package/dist/runner/SwarmRouter.js +24 -0
  34. package/dist/runner/ToolDispatcher.d.ts +13 -0
  35. package/dist/runner/ToolDispatcher.js +34 -0
  36. package/dist/scheduler/AgentScheduler.d.ts +48 -0
  37. package/dist/scheduler/AgentScheduler.js +111 -0
  38. package/dist/session/ContextStore.d.ts +28 -0
  39. package/dist/session/ContextStore.js +85 -0
  40. package/dist/session/GoalManager.d.ts +43 -0
  41. package/dist/session/GoalManager.js +108 -0
  42. package/dist/session/MemoryStore.d.ts +27 -0
  43. package/dist/session/MemoryStore.js +92 -0
  44. package/dist/session/SessionManager.d.ts +24 -0
  45. package/dist/session/SessionManager.js +57 -0
  46. package/dist/setup/SetupWizard.d.ts +13 -0
  47. package/dist/setup/SetupWizard.js +71 -0
  48. package/dist/tools/MarketSentiment.d.ts +20 -0
  49. package/dist/tools/MarketSentiment.js +211 -0
  50. package/dist/tools/NewsSentiment.d.ts +36 -0
  51. package/dist/tools/NewsSentiment.js +141 -0
  52. package/dist/tools/PriceFeed.d.ts +85 -0
  53. package/dist/tools/PriceFeed.js +134 -0
  54. package/dist/tools/TechnicalAnalysis.d.ts +50 -0
  55. package/dist/tools/TechnicalAnalysis.js +234 -0
  56. package/dist/tui/App.d.ts +20 -0
  57. package/dist/tui/App.js +484 -0
  58. package/dist/tui/ModelSelector.d.ts +18 -0
  59. package/dist/tui/ModelSelector.js +59 -0
  60. package/dist/tui/REPL.d.ts +22 -0
  61. package/dist/tui/REPL.js +48 -0
  62. package/dist/tui/StatusBar.d.ts +14 -0
  63. package/dist/tui/StatusBar.js +13 -0
  64. package/dist/tui/theme.d.ts +27 -0
  65. package/dist/tui/theme.js +38 -0
  66. package/dist/util/safeLog.d.ts +8 -0
  67. package/dist/util/safeLog.js +38 -0
  68. package/package.json +64 -0
@@ -0,0 +1,134 @@
1
+ /**
2
+ * PriceFeed — real-time price aggregation via DexScreener API.
3
+ * Primary: AIAIAI token price (hardcoded address).
4
+ * Secondary: query any token by address.
5
+ */
6
+ import { Type } from "@sinclair/typebox";
7
+ const AIAIAI_TOKEN = "AVPJS61gZmWKtaEpb7qYPKo8Fk2xQUsayYQxPiPMpump";
8
+ export class PriceFeed {
9
+ cachedAiaiPrice = null;
10
+ lastFetch = 0;
11
+ cacheDuration = 30_000; // 30s cache
12
+ async getAiaiaiPrice() {
13
+ if (this.cachedAiaiPrice && Date.now() - this.lastFetch < this.cacheDuration) {
14
+ return this.cachedAiaiPrice;
15
+ }
16
+ return this.fetchToken(AIAIAI_TOKEN);
17
+ }
18
+ async fetchToken(tokenAddress) {
19
+ const url = `https://api.dexscreener.com/tokens/v1/solana/${tokenAddress}`;
20
+ try {
21
+ const response = await fetch(url);
22
+ if (!response.ok) {
23
+ return this.fallbackPrice(tokenAddress);
24
+ }
25
+ const data = await response.json();
26
+ if (!data || data.length === 0) {
27
+ return this.fallbackPrice(tokenAddress);
28
+ }
29
+ const pair = data[0];
30
+ const result = {
31
+ tokenAddress,
32
+ symbol: pair.baseToken.symbol,
33
+ name: pair.baseToken.name,
34
+ priceUsd: pair.priceUsd,
35
+ priceNative: pair.priceNative,
36
+ liquidityUsd: pair.liquidity?.usd ?? 0,
37
+ fdv: pair.fdv ?? null,
38
+ marketCap: pair.marketCap ?? null,
39
+ volume24h: pair.volume?.["h24"] ?? 0,
40
+ priceChange24h: pair.priceChange?.["h24"] ?? 0,
41
+ buys24h: pair.txns?.["h24"]?.buys ?? 0,
42
+ sells24h: pair.txns?.["h24"]?.sells ?? 0,
43
+ dexUrl: pair.url,
44
+ };
45
+ if (tokenAddress === AIAIAI_TOKEN) {
46
+ this.cachedAiaiPrice = result;
47
+ this.lastFetch = Date.now();
48
+ }
49
+ return result;
50
+ }
51
+ catch {
52
+ return this.fallbackPrice(tokenAddress);
53
+ }
54
+ }
55
+ fallbackPrice(tokenAddress) {
56
+ return {
57
+ tokenAddress,
58
+ symbol: tokenAddress === AIAIAI_TOKEN ? "AIAIAI" : "UNKNOWN",
59
+ name: tokenAddress === AIAIAI_TOKEN ? "AIAIAI Chain" : "Unknown Token",
60
+ priceUsd: null,
61
+ priceNative: "0",
62
+ liquidityUsd: 0,
63
+ fdv: null,
64
+ marketCap: null,
65
+ volume24h: 0,
66
+ priceChange24h: 0,
67
+ buys24h: 0,
68
+ sells24h: 0,
69
+ dexUrl: `https://dexscreener.com/solana/${tokenAddress}`,
70
+ };
71
+ }
72
+ tickerLine(maxLength = 6) {
73
+ try {
74
+ const p = this.cachedAiaiPrice ?? this.getAiaiaiPriceSync();
75
+ if (!p || !p.priceUsd)
76
+ return "";
77
+ const price = parseFloat(p.priceUsd).toFixed(6);
78
+ const change = p.priceChange24h;
79
+ const arrow = change > 0 ? "▲" : change < 0 ? "▼" : "─";
80
+ return `$AIAIAI $${price} ${arrow}${Math.abs(change).toFixed(2)}%`.slice(0, 40);
81
+ }
82
+ catch {
83
+ return "";
84
+ }
85
+ }
86
+ getAiaiaiPriceSync() {
87
+ return this.cachedAiaiPrice;
88
+ }
89
+ priceLine() {
90
+ const p = this.getAiaiaiPriceSync();
91
+ if (!p || !p.priceUsd)
92
+ return "$AIAIAI: loading...";
93
+ return `$AIAIAI $${parseFloat(p.priceUsd).toFixed(6)} | ${p.priceChange24h > 0 ? "+" : ""}${p.priceChange24h.toFixed(2)}%`;
94
+ }
95
+ // ── Tools ───────────────────────────────────────────────────────────────
96
+ getAiaiaiPriceParams = Type.Object({});
97
+ getTokenPriceParams = Type.Object({
98
+ address: Type.String({ description: "Token contract address on Solana" }),
99
+ });
100
+ async getAiaiaiPriceTool() {
101
+ const p = await this.getAiaiaiPrice();
102
+ const lines = [
103
+ `Token: $${p.symbol} (${p.name})`,
104
+ `Address: ${p.tokenAddress}`,
105
+ `Price USD: ${p.priceUsd ? `$${parseFloat(p.priceUsd).toFixed(8)}` : "N/A"}`,
106
+ `Price SOL: ${parseFloat(p.priceNative).toFixed(8)} SOL`,
107
+ `24h Change: ${p.priceChange24h > 0 ? "+" : ""}${p.priceChange24h.toFixed(2)}%`,
108
+ `24h Volume: $${p.volume24h.toLocaleString()}`,
109
+ `24h Buys: ${p.buys24h} | Sells: ${p.sells24h}`,
110
+ `Liquidity: $${p.liquidityUsd.toLocaleString()}`,
111
+ `FDV: ${p.fdv ? `$${p.fdv.toLocaleString()}` : "N/A"}`,
112
+ `Market Cap: ${p.marketCap ? `$${p.marketCap.toLocaleString()}` : "N/A"}`,
113
+ `DEX: ${p.dexUrl}`,
114
+ ];
115
+ return { content: [{ type: "text", text: lines.join("\n") }] };
116
+ }
117
+ async getTokenPriceTool(_id, params) {
118
+ const address = params.address;
119
+ const p = await this.fetchToken(address);
120
+ const lines = [
121
+ `Token: $${p.symbol} (${p.name})`,
122
+ `Address: ${p.tokenAddress}`,
123
+ `Price USD: ${p.priceUsd ? `$${parseFloat(p.priceUsd).toFixed(8)}` : "N/A"}`,
124
+ `Price NATIVE: ${parseFloat(p.priceNative).toFixed(8)}`,
125
+ `24h Change: ${p.priceChange24h > 0 ? "+" : ""}${p.priceChange24h.toFixed(2)}%`,
126
+ `24h Volume: $${p.volume24h.toLocaleString()}`,
127
+ `Buys/Sells: ${p.buys24h}/${p.sells24h}`,
128
+ `Liquidity: $${p.liquidityUsd.toLocaleString()}`,
129
+ ];
130
+ return { content: [{ type: "text", text: lines.join("\n") }] };
131
+ }
132
+ }
133
+ export const priceFeed = new PriceFeed();
134
+ //# sourceMappingURL=PriceFeed.js.map
@@ -0,0 +1,50 @@
1
+ /**
2
+ * TechnicalAnalysis — RSI, MACD, Bollinger Bands, EMA, SMA, ATR.
3
+ * Works with OHLCV candle data. Tools for the agent to query.
4
+ */
5
+ import type { ToolResult } from "../api/ExtensionAPI.js";
6
+ export interface OHLCV {
7
+ timestamp: number;
8
+ open: number;
9
+ high: number;
10
+ low: number;
11
+ close: number;
12
+ volume: number;
13
+ }
14
+ export interface AnalysisResult {
15
+ indicator: string;
16
+ value: number | number[];
17
+ signal: "bullish" | "bearish" | "neutral";
18
+ details?: string;
19
+ }
20
+ export declare function sma(data: number[], period: number): number[];
21
+ export declare function ema(data: number[], period: number): number[];
22
+ export declare function rsi(data: number[], period?: number): number[];
23
+ export declare function rsiSignal(rsiValues: number[], currentPrice: number, prices: number[]): AnalysisResult;
24
+ export declare function macd(data: number[], fast?: number, slow?: number, signalPeriod?: number): {
25
+ macd: number[];
26
+ signal: number[];
27
+ histogram: number[];
28
+ };
29
+ export declare function macdSignal(macdData: ReturnType<typeof macd>): AnalysisResult;
30
+ export declare function bollingerBands(data: number[], period?: number, stdDev?: number): {
31
+ upper: number[];
32
+ middle: number[];
33
+ lower: number[];
34
+ };
35
+ export declare function bollingerSignal(bb: ReturnType<typeof bollingerBands>, currentPrice: number): AnalysisResult;
36
+ export declare function atr(candles: OHLCV[], period?: number): number;
37
+ export declare function fullAnalysis(candles: OHLCV[]): AnalysisResult[];
38
+ export declare const getCandlesParams: import("@sinclair/typebox").TObject<{
39
+ symbol: import("@sinclair/typebox").TString;
40
+ interval: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
41
+ limit: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
42
+ }>;
43
+ export declare const analyzeTAParams: import("@sinclair/typebox").TObject<{
44
+ prices: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TNumber>;
45
+ highs: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TNumber>>;
46
+ lows: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TNumber>>;
47
+ volumes: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TNumber>>;
48
+ }>;
49
+ export declare function getCandlesTool(_id: string, params: Record<string, unknown>): Promise<ToolResult>;
50
+ //# sourceMappingURL=TechnicalAnalysis.d.ts.map
@@ -0,0 +1,234 @@
1
+ /**
2
+ * TechnicalAnalysis — RSI, MACD, Bollinger Bands, EMA, SMA, ATR.
3
+ * Works with OHLCV candle data. Tools for the agent to query.
4
+ */
5
+ import { Type } from "@sinclair/typebox";
6
+ // ── SMA ──────────────────────────────────────────────────────────────────────
7
+ export function sma(data, period) {
8
+ const result = [];
9
+ for (let i = period - 1; i < data.length; i++) {
10
+ let sum = 0;
11
+ for (let j = 0; j < period; j++)
12
+ sum += data[i - j];
13
+ result.push(sum / period);
14
+ }
15
+ return result;
16
+ }
17
+ // ── EMA ──────────────────────────────────────────────────────────────────────
18
+ export function ema(data, period) {
19
+ const result = [];
20
+ const k = 2 / (period + 1);
21
+ const initialSma = data.slice(0, period).reduce((a, b) => a + b, 0) / period;
22
+ result.push(initialSma);
23
+ for (let i = period; i < data.length; i++) {
24
+ result.push(data[i] * k + result[result.length - 1] * (1 - k));
25
+ }
26
+ return result;
27
+ }
28
+ // ── RSI ──────────────────────────────────────────────────────────────────────
29
+ export function rsi(data, period = 14) {
30
+ const result = [];
31
+ const gains = [];
32
+ const losses = [];
33
+ for (let i = 1; i < data.length; i++) {
34
+ const diff = data[i] - data[i - 1];
35
+ gains.push(Math.max(0, diff));
36
+ losses.push(Math.max(0, -diff));
37
+ }
38
+ for (let i = period; i < gains.length; i++) {
39
+ let avgGain = 0, avgLoss = 0;
40
+ for (let j = 0; j < period; j++) {
41
+ avgGain += gains[i - j];
42
+ avgLoss += losses[i - j];
43
+ }
44
+ avgGain /= period;
45
+ avgLoss /= period;
46
+ if (avgLoss === 0) {
47
+ result.push(100);
48
+ continue;
49
+ }
50
+ const rs = avgGain / avgLoss;
51
+ result.push(100 - 100 / (1 + rs));
52
+ }
53
+ return result;
54
+ }
55
+ export function rsiSignal(rsiValues, currentPrice, prices) {
56
+ const last = rsiValues[rsiValues.length - 1];
57
+ let signal = "neutral";
58
+ if (last > 70)
59
+ signal = "bearish";
60
+ else if (last < 30)
61
+ signal = "bullish";
62
+ return {
63
+ indicator: "RSI",
64
+ value: parseFloat(last.toFixed(2)),
65
+ signal,
66
+ details: `RSI(14) = ${last.toFixed(2)}${last > 70 ? " — overbought" : last < 30 ? " — oversold" : " — neutral zone"}`,
67
+ };
68
+ }
69
+ // ── MACD ─────────────────────────────────────────────────────────────────────
70
+ export function macd(data, fast = 12, slow = 26, signalPeriod = 9) {
71
+ const fastEma = ema(data, fast);
72
+ const slowEma = ema(data, slow);
73
+ const macdLine = [];
74
+ // MACD line is fast EMA - slow EMA (aligned)
75
+ const offset = slow - fast;
76
+ for (let i = 0; i < slowEma.length; i++) {
77
+ macdLine.push(fastEma[i + offset] - slowEma[i]);
78
+ }
79
+ const signal = ema(macdLine, signalPeriod);
80
+ // Shift signal to align
81
+ const sigShift = signalPeriod - 1;
82
+ const histogram = [];
83
+ for (let i = 0; i < macdLine.length - sigShift; i++) {
84
+ histogram.push(macdLine[i + sigShift] - signal[i]);
85
+ }
86
+ // Trim macdLine to match histogram length
87
+ const trimmed = macdLine.slice(sigShift);
88
+ return { macd: trimmed, signal, histogram };
89
+ }
90
+ export function macdSignal(macdData) {
91
+ const hist = macdData.histogram;
92
+ const last = hist[hist.length - 1] ?? 0;
93
+ const prev = hist[hist.length - 2] ?? 0;
94
+ let signal = "neutral";
95
+ if (last > 0 && prev <= 0)
96
+ signal = "bullish";
97
+ else if (last < 0 && prev >= 0)
98
+ signal = "bearish";
99
+ return {
100
+ indicator: "MACD",
101
+ value: parseFloat(last.toFixed(6)),
102
+ signal,
103
+ details: `MACD histogram: ${last.toFixed(6)}${signal !== "neutral" ? ` — ${signal} crossover` : ""}`,
104
+ };
105
+ }
106
+ // ── Bollinger Bands ──────────────────────────────────────────────────────────
107
+ export function bollingerBands(data, period = 20, stdDev = 2) {
108
+ const middle = sma(data, period);
109
+ const upper = [];
110
+ const lower = [];
111
+ for (let i = 0; i < middle.length; i++) {
112
+ const start = i;
113
+ let sumSq = 0;
114
+ for (let j = 0; j < period; j++) {
115
+ const idx = start + j;
116
+ if (idx < data.length)
117
+ sumSq += (data[idx] - middle[i]) ** 2;
118
+ }
119
+ const std = Math.sqrt(sumSq / period);
120
+ upper.push(middle[i] + stdDev * std);
121
+ lower.push(middle[i] - stdDev * std);
122
+ }
123
+ return { upper, middle, lower };
124
+ }
125
+ export function bollingerSignal(bb, currentPrice) {
126
+ const lastUpper = bb.upper[bb.upper.length - 1];
127
+ const lastLower = bb.lower[bb.lower.length - 1];
128
+ const lastMid = bb.middle[bb.middle.length - 1];
129
+ let signal = "neutral";
130
+ if (currentPrice >= lastUpper)
131
+ signal = "bearish";
132
+ else if (currentPrice <= lastLower)
133
+ signal = "bullish";
134
+ return {
135
+ indicator: "Bollinger",
136
+ value: [parseFloat(lastUpper.toFixed(6)), parseFloat(lastMid.toFixed(6)), parseFloat(lastLower.toFixed(6))],
137
+ signal,
138
+ details: signal === "bearish" ? "Price at upper band — overextended" : signal === "bullish" ? "Price at lower band — oversold" : "Within bands",
139
+ };
140
+ }
141
+ // ── ATR ──────────────────────────────────────────────────────────────────────
142
+ export function atr(candles, period = 14) {
143
+ const trueRanges = [];
144
+ for (let i = 1; i < candles.length; i++) {
145
+ const high = candles[i].high;
146
+ const low = candles[i].low;
147
+ const prevClose = candles[i - 1].close;
148
+ trueRanges.push(Math.max(high - low, Math.abs(high - prevClose), Math.abs(low - prevClose)));
149
+ }
150
+ if (trueRanges.length < period)
151
+ return trueRanges.reduce((a, b) => a + b, 0) / Math.max(1, trueRanges.length);
152
+ return trueRanges.slice(-period).reduce((a, b) => a + b, 0) / period;
153
+ }
154
+ // ── Full Analysis ────────────────────────────────────────────────────────────
155
+ export function fullAnalysis(candles) {
156
+ const closes = candles.map(c => c.close);
157
+ if (closes.length < 30)
158
+ return [];
159
+ const results = [];
160
+ results.push(rsiSignal(rsi(closes, 14), closes[closes.length - 1], closes));
161
+ results.push(macdSignal(macd(closes, 12, 26, 9)));
162
+ const bb = bollingerBands(closes, 20, 2);
163
+ results.push(bollingerSignal(bb, closes[closes.length - 1]));
164
+ const atrValue = atr(candles, 14);
165
+ results.push({
166
+ indicator: "ATR",
167
+ value: parseFloat(atrValue.toFixed(6)),
168
+ signal: "neutral",
169
+ details: `ATR(14) = ${atrValue.toFixed(6)}`,
170
+ });
171
+ // Overall signal — weighted
172
+ const bullish = results.filter(r => r.signal === "bullish").length;
173
+ const bearish = results.filter(r => r.signal === "bearish").length;
174
+ const overall = bullish > bearish ? "bullish" : bearish > bullish ? "bearish" : "neutral";
175
+ results.push({
176
+ indicator: "SUMMARY",
177
+ value: results.length,
178
+ signal: overall,
179
+ details: `${bullish} bullish, ${bearish} bearish, ${results.length - bullish - bearish} neutral — overall ${overall}`,
180
+ });
181
+ return results;
182
+ }
183
+ // ── Tools ────────────────────────────────────────────────────────────────────
184
+ export const getCandlesParams = Type.Object({
185
+ symbol: Type.String({ description: "Trading pair symbol (e.g., BTCUSDT, SOLUSDT)" }),
186
+ interval: Type.Optional(Type.String({ description: "Candle interval: 1m, 5m, 15m, 1h, 4h, 1d", default: "1d" })),
187
+ limit: Type.Optional(Type.Number({ description: "Number of candles", default: 50 })),
188
+ });
189
+ export const analyzeTAParams = Type.Object({
190
+ prices: Type.Array(Type.Number({ description: "Closing prices" })),
191
+ highs: Type.Optional(Type.Array(Type.Number({ description: "High prices" }))),
192
+ lows: Type.Optional(Type.Array(Type.Number({ description: "Low prices" }))),
193
+ volumes: Type.Optional(Type.Array(Type.Number({ description: "Volumes" }))),
194
+ });
195
+ export async function getCandlesTool(_id, params) {
196
+ const symbol = params.symbol;
197
+ const interval = params.interval || "1d";
198
+ const limit = params.limit || 50;
199
+ try {
200
+ const response = await fetch(`https://api.binance.com/api/v3/klines?symbol=${symbol}&interval=${interval}&limit=${limit}`);
201
+ if (!response.ok) {
202
+ return { content: [{ type: "text", text: `Failed to fetch candles for ${symbol}: ${response.status}` }] };
203
+ }
204
+ const data = await response.json();
205
+ const candles = data.map(k => ({
206
+ timestamp: k[0],
207
+ open: parseFloat(k[1]),
208
+ high: parseFloat(k[2]),
209
+ low: parseFloat(k[3]),
210
+ close: parseFloat(k[4]),
211
+ volume: parseFloat(k[5]),
212
+ }));
213
+ const closes = candles.map(c => c.close);
214
+ const results = fullAnalysis(candles);
215
+ const lines = [
216
+ `--- ${symbol} ${interval} candles (${candles.length}) ---`,
217
+ `Last: $${closes[closes.length - 1].toFixed(6)}`,
218
+ `Range: $${Math.min(...closes).toFixed(6)} - $${Math.max(...closes).toFixed(6)}`,
219
+ ``,
220
+ ...results.map(r => {
221
+ const icon = r.signal === "bullish" ? "🟢" : r.signal === "bearish" ? "🔴" : "⚪";
222
+ return `${icon} ${r.indicator}: ${JSON.stringify(typeof r.value === "number" ? r.value.toFixed(4) : r.value)} — ${r.details ?? ""}`;
223
+ }),
224
+ ];
225
+ return {
226
+ content: [{ type: "text", text: lines.join("\n") }],
227
+ details: { candles: candles.slice(-5), analysis: results },
228
+ };
229
+ }
230
+ catch (e) {
231
+ return { content: [{ type: "text", text: `Error fetching candles: ${e instanceof Error ? e.message : String(e)}` }], isError: true };
232
+ }
233
+ }
234
+ //# sourceMappingURL=TechnicalAnalysis.js.map
@@ -0,0 +1,20 @@
1
+ /**
2
+ * App — root Ink component. Multi-pane TUI with sidebar (price, news, context)
3
+ * and main REPL area.
4
+ */
5
+ import React from "react";
6
+ import { Registry } from "../api/Registry.js";
7
+ import type { ModelRegistry } from "../models/ModelRegistry.js";
8
+ import type { CostTracker } from "../models/CostTracker.js";
9
+ export interface AppProps {
10
+ registry: Registry;
11
+ systemPrompt?: string;
12
+ chain?: string;
13
+ modelReg?: ModelRegistry;
14
+ costTracker?: CostTracker;
15
+ onNotifyReady?: (fn: (msg: string) => void) => void;
16
+ onStatusReady?: (fn: (key: string, val: string) => void) => void;
17
+ onModelSelectorReady?: (fn: (query?: string) => void) => void;
18
+ }
19
+ export declare function App({ registry, systemPrompt, chain: initialChain, modelReg, costTracker, onNotifyReady, onStatusReady, onModelSelectorReady, }: AppProps): React.JSX.Element;
20
+ //# sourceMappingURL=App.d.ts.map