@aiaiaichain/agent 0.1.3 → 0.1.5
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.
- package/README.md +2 -2
- package/dist/cli.js +274 -26
- package/dist/core/ChainConfig.js +1 -1
- package/dist/core/SystemMonitor.d.ts +32 -0
- package/dist/core/SystemMonitor.js +89 -0
- package/dist/index.d.ts +17 -2
- package/dist/index.js +18 -1
- package/dist/models/ModelRegistry.js +12 -4
- package/dist/runner/AgentRunner.d.ts +2 -0
- package/dist/runner/AgentRunner.js +18 -1
- package/dist/runner/ModelClient.js +109 -48
- package/dist/session/SessionManager.d.ts +1 -0
- package/dist/session/SessionManager.js +8 -2
- package/dist/session/SessionStore.d.ts +45 -0
- package/dist/session/SessionStore.js +128 -0
- package/dist/tools/CrossTools.d.ts +52 -0
- package/dist/tools/CrossTools.js +190 -0
- package/dist/tools/MarketSentiment.js +22 -13
- package/dist/tools/NewsSentiment.js +9 -3
- package/dist/tools/PriceFeed.js +11 -4
- package/dist/tools/TechnicalAnalysis.js +2 -1
- package/dist/tools/TokenCalendar.d.ts +24 -0
- package/dist/tools/TokenCalendar.js +81 -0
- package/dist/tools/TokenSecurityScanner.d.ts +22 -0
- package/dist/tools/TokenSecurityScanner.js +102 -0
- package/dist/tools/TransactionSim.d.ts +17 -0
- package/dist/tools/TransactionSim.js +78 -0
- package/dist/tui/App.d.ts +4 -3
- package/dist/tui/App.js +371 -118
- package/dist/tui/REPL.d.ts +2 -1
- package/dist/tui/REPL.js +190 -16
- package/dist/tui/Sparkline.d.ts +21 -0
- package/dist/tui/Sparkline.js +44 -0
- package/dist/tui/StatusBar.d.ts +5 -1
- package/dist/tui/StatusBar.js +6 -4
- package/dist/tui/ThemePresets.d.ts +25 -0
- package/dist/tui/ThemePresets.js +117 -0
- package/dist/util/clipboard.d.ts +9 -0
- package/dist/util/clipboard.js +26 -0
- package/dist/util/commandSuggest.d.ts +7 -0
- package/dist/util/commandSuggest.js +44 -0
- package/dist/util/confirmation.d.ts +6 -0
- package/dist/util/confirmation.js +16 -0
- package/dist/util/errorHandler.d.ts +3 -0
- package/dist/util/errorHandler.js +28 -0
- package/dist/util/logger.d.ts +11 -0
- package/dist/util/logger.js +43 -0
- package/dist/util/processManager.d.ts +5 -0
- package/dist/util/processManager.js +39 -0
- package/dist/util/resilientFetch.d.ts +21 -0
- package/dist/util/resilientFetch.js +94 -0
- package/dist/util/responseCache.d.ts +27 -0
- package/dist/util/responseCache.js +54 -0
- package/dist/util/safeLog.d.ts +4 -5
- package/dist/util/safeLog.js +68 -30
- package/dist/util/scheduler.d.ts +14 -0
- package/dist/util/scheduler.js +75 -0
- package/dist/util/webhooks.d.ts +9 -0
- package/dist/util/webhooks.js +75 -0
- package/dist/wallet/ActionFeed.js +12 -4
- package/dist/wallet/AgentWallet.d.ts +2 -0
- package/dist/wallet/AgentWallet.js +31 -5
- package/dist/wallet/ProfitTracker.d.ts +30 -0
- package/dist/wallet/ProfitTracker.js +93 -0
- package/docs/COMMANDS.md +40 -9
- package/docs/README.md +2 -0
- package/package.json +5 -3
- package/scripts/postinstall.js +34 -0
package/dist/tui/REPL.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* REPL — scrolling message history +
|
|
2
|
+
* REPL — scrolling message history + feature-rich input box.
|
|
3
|
+
* Supports: multi-line (Shift+Enter), command history (↑/↓), tab completion.
|
|
3
4
|
*/
|
|
4
5
|
import React from "react";
|
|
5
6
|
export interface ChatMessage {
|
package/dist/tui/REPL.js
CHANGED
|
@@ -1,12 +1,33 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
/**
|
|
3
|
-
* REPL — scrolling message history +
|
|
3
|
+
* REPL — scrolling message history + feature-rich input box.
|
|
4
|
+
* Supports: multi-line (Shift+Enter), command history (↑/↓), tab completion.
|
|
4
5
|
*/
|
|
5
|
-
import { useState, useCallback } from "react";
|
|
6
|
+
import { useState, useCallback, useRef } from "react";
|
|
6
7
|
import { Box, Text, useStdout, useInput } from "ink";
|
|
7
|
-
import TextInput from "ink-text-input";
|
|
8
8
|
import { AIAIAI_COLORS } from "./theme.js";
|
|
9
9
|
const MAX_VISIBLE = 40;
|
|
10
|
+
const MAX_HISTORY = 100;
|
|
11
|
+
// ── Command completions ─────────────────────────────────────────────────────
|
|
12
|
+
const COMMANDS = [
|
|
13
|
+
"token info", "token security", "token holders", "token traders",
|
|
14
|
+
"track kol", "track smartmoney", "track follow-wallet",
|
|
15
|
+
"market kline", "market trending", "market trenches", "market signal",
|
|
16
|
+
"watch", "unwatch", "watchlist", "alerts", "alert above", "alert below",
|
|
17
|
+
"compare",
|
|
18
|
+
"price", "news", "models", "cost", "model", "clear",
|
|
19
|
+
"wallet", "deposit", "burn", "actions", "activity", "fees",
|
|
20
|
+
"keys", "providers", "goals", "goal add", "goal done", "goal list",
|
|
21
|
+
"schedule", "sessions", "resume", "memory", "update", "gmgn", "help",
|
|
22
|
+
"exit", "quit",
|
|
23
|
+
];
|
|
24
|
+
function getCompletions(prefix) {
|
|
25
|
+
if (!prefix || prefix === "/")
|
|
26
|
+
return COMMANDS.map(c => `/${c}`);
|
|
27
|
+
const p = prefix.startsWith("/") ? prefix.slice(1) : prefix;
|
|
28
|
+
return COMMANDS.filter(c => c.startsWith(p)).map(c => `/${c}`);
|
|
29
|
+
}
|
|
30
|
+
// ── Message components ──────────────────────────────────────────────────────
|
|
10
31
|
function MessageLine({ msg }) {
|
|
11
32
|
const time = new Date(msg.ts).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" });
|
|
12
33
|
if (msg.role === "user") {
|
|
@@ -24,25 +45,178 @@ function MessageLine({ msg }) {
|
|
|
24
45
|
if (msg.role === "notify") {
|
|
25
46
|
return (_jsx(Box, { borderStyle: "round", borderColor: AIAIAI_COLORS.accent, marginY: 1, paddingX: 1, children: _jsx(Text, { wrap: "wrap", children: msg.content }) }));
|
|
26
47
|
}
|
|
27
|
-
// system
|
|
48
|
+
// system — dimmed
|
|
28
49
|
return (_jsx(Box, { flexDirection: "row", gap: 1, children: _jsx(Text, { color: AIAIAI_COLORS.dim, wrap: "wrap", children: msg.content }) }));
|
|
29
50
|
}
|
|
51
|
+
function InputBox({ value, onChange, onSubmit, disabled, onAbort }) {
|
|
52
|
+
const [cursor, setCursor] = useState(value.length);
|
|
53
|
+
const [history, setHistory] = useState([]);
|
|
54
|
+
const [historyIdx, setHistoryIdx] = useState(-1);
|
|
55
|
+
const [completions, setCompletions] = useState([]);
|
|
56
|
+
const [completionIdx, setCompletionIdx] = useState(-1);
|
|
57
|
+
const [showCompletions, setShowCompletions] = useState(false);
|
|
58
|
+
const valueRef = useRef(value);
|
|
59
|
+
const cursorRef = useRef(cursor);
|
|
60
|
+
valueRef.current = value;
|
|
61
|
+
cursorRef.current = cursor;
|
|
62
|
+
// Messages scroll handled by Ink container
|
|
63
|
+
const insertAtCursor = useCallback((text) => {
|
|
64
|
+
const before = valueRef.current.slice(0, cursorRef.current);
|
|
65
|
+
const after = valueRef.current.slice(cursorRef.current);
|
|
66
|
+
const newVal = before + text + after;
|
|
67
|
+
onChange(newVal);
|
|
68
|
+
setCursor(cursorRef.current + text.length);
|
|
69
|
+
}, [onChange]);
|
|
70
|
+
const doSubmit = useCallback(() => {
|
|
71
|
+
const val = valueRef.current;
|
|
72
|
+
if (!val.trim() || disabled)
|
|
73
|
+
return;
|
|
74
|
+
setHistory(prev => [val, ...prev].slice(0, MAX_HISTORY));
|
|
75
|
+
setHistoryIdx(-1);
|
|
76
|
+
setShowCompletions(false);
|
|
77
|
+
onChange("");
|
|
78
|
+
setCursor(0);
|
|
79
|
+
onSubmit(val);
|
|
80
|
+
}, [disabled, onChange, onSubmit]);
|
|
81
|
+
useInput((input, key) => {
|
|
82
|
+
// Always handle Escape for abort
|
|
83
|
+
if (key.escape) {
|
|
84
|
+
if (disabled) {
|
|
85
|
+
onAbort();
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
setShowCompletions(false);
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
if (disabled)
|
|
92
|
+
return;
|
|
93
|
+
// Tab completion
|
|
94
|
+
if (key.tab) {
|
|
95
|
+
const val = valueRef.current;
|
|
96
|
+
if (!showCompletions) {
|
|
97
|
+
// Check only when typing a command
|
|
98
|
+
if (val.startsWith("/") && val.length > 0) {
|
|
99
|
+
const comps = getCompletions(val);
|
|
100
|
+
if (comps.length === 1 && comps[0] !== val) {
|
|
101
|
+
// Auto-complete if only one match
|
|
102
|
+
onChange(comps[0] + " ");
|
|
103
|
+
setCursor(comps[0].length + 1);
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
if (comps.length > 0) {
|
|
107
|
+
setCompletions(comps);
|
|
108
|
+
setCompletionIdx(0);
|
|
109
|
+
setShowCompletions(true);
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
// Cycle through completions
|
|
116
|
+
if (completions.length > 0) {
|
|
117
|
+
const nextIdx = (completionIdx + 1) % completions.length;
|
|
118
|
+
setCompletionIdx(nextIdx);
|
|
119
|
+
// Show the completion
|
|
120
|
+
const comp = completions[nextIdx];
|
|
121
|
+
onChange(comp + " ");
|
|
122
|
+
setCursor(comp.length + 1);
|
|
123
|
+
}
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
// Close completions on any other key
|
|
127
|
+
if (showCompletions)
|
|
128
|
+
setShowCompletions(false);
|
|
129
|
+
// Enter submits
|
|
130
|
+
if (key.return) {
|
|
131
|
+
// Shift+Enter = new line, Enter = submit
|
|
132
|
+
if (input === "\r" && !key.shift) {
|
|
133
|
+
doSubmit();
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
// Shift+Enter inserts newline
|
|
137
|
+
if (key.shift || input === "\u0003") {
|
|
138
|
+
insertAtCursor("\n");
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
// History navigation (↑/↓)
|
|
143
|
+
if (key.upArrow) {
|
|
144
|
+
if (history.length === 0)
|
|
145
|
+
return;
|
|
146
|
+
const newIdx = historyIdx < history.length - 1 ? historyIdx + 1 : historyIdx;
|
|
147
|
+
setHistoryIdx(newIdx);
|
|
148
|
+
onChange(history[newIdx]);
|
|
149
|
+
setCursor(history[newIdx].length);
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
if (key.downArrow) {
|
|
153
|
+
if (historyIdx <= 0) {
|
|
154
|
+
setHistoryIdx(-1);
|
|
155
|
+
onChange("");
|
|
156
|
+
setCursor(0);
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
const newIdx = historyIdx - 1;
|
|
160
|
+
setHistoryIdx(newIdx);
|
|
161
|
+
onChange(history[newIdx]);
|
|
162
|
+
setCursor(history[newIdx].length);
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
// Left/right arrow — update cursor tracking
|
|
166
|
+
if (key.leftArrow) {
|
|
167
|
+
setCursor(Math.max(0, cursorRef.current - 1));
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
if (key.rightArrow) {
|
|
171
|
+
setCursor(Math.min(valueRef.current.length, cursorRef.current + 1));
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
// Backspace
|
|
175
|
+
if (key.backspace || key.delete) {
|
|
176
|
+
if (cursorRef.current <= 0)
|
|
177
|
+
return;
|
|
178
|
+
const before = valueRef.current.slice(0, cursorRef.current - 1);
|
|
179
|
+
const after = valueRef.current.slice(cursorRef.current);
|
|
180
|
+
onChange(before + after);
|
|
181
|
+
setCursor(cursorRef.current - 1);
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
// Printable character
|
|
185
|
+
if (input && input.length === 1 && input.charCodeAt(0) >= 32) {
|
|
186
|
+
insertAtCursor(input);
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
const placeholder = disabled ? "thinking…" : "message or /command";
|
|
191
|
+
const displayValue = value || placeholder;
|
|
192
|
+
const inputLines = displayValue.split("\n");
|
|
193
|
+
const inputHeight = Math.min(inputLines.length, 5); // max 5 visible lines
|
|
194
|
+
return (_jsxs(Box, { flexDirection: "column", children: [showCompletions && completions.length > 0 && (_jsxs(Box, { borderStyle: "single", borderColor: AIAIAI_COLORS.accent, paddingX: 1, flexDirection: "column", marginBottom: 0, children: [completions.slice(0, 8).map((c, i) => (_jsxs(Text, { color: i === completionIdx ? AIAIAI_COLORS.accent : AIAIAI_COLORS.muted, bold: i === completionIdx, children: [i === completionIdx ? "▸ " : " ", c] }, c))), completions.length > 8 && (_jsxs(Text, { color: AIAIAI_COLORS.dim, children: [" \u2026", completions.length - 8, " more"] }))] })), _jsx(Box, { borderStyle: "round", borderColor: disabled ? AIAIAI_COLORS.dim : AIAIAI_COLORS.accent, paddingX: 1, paddingY: inputHeight > 1 ? 0 : 0, flexDirection: "column", marginTop: 1, children: _jsxs(Box, { flexDirection: "row", children: [_jsx(Text, { color: AIAIAI_COLORS.accent, bold: true, children: "\u203A " }), _jsx(Box, { flexDirection: "column", flexGrow: 1, children: value ? (
|
|
195
|
+
// Show actual input with cursor
|
|
196
|
+
inputLines.slice(0, 5).map((line, i) => {
|
|
197
|
+
const isCursorLine = i === Math.min(cursorRef.current, inputLines.length - 1);
|
|
198
|
+
const cursorCol = isCursorLine
|
|
199
|
+
? cursorRef.current - inputLines.slice(0, i).join("\n").length - (i > 0 ? 1 : 0)
|
|
200
|
+
: line.length;
|
|
201
|
+
const cursorColClamped = Math.min(cursorCol, line.length);
|
|
202
|
+
const before = line.slice(0, cursorColClamped);
|
|
203
|
+
const at = line[cursorColClamped] || " ";
|
|
204
|
+
const after = line.slice(cursorColClamped + 1);
|
|
205
|
+
return (_jsxs(Text, { wrap: "truncate-end", children: [before, _jsx(Text, { inverse: true, children: at }), after] }, i));
|
|
206
|
+
})) : (_jsx(Text, { color: AIAIAI_COLORS.dim, children: placeholder })) })] }) })] }));
|
|
207
|
+
}
|
|
30
208
|
export function REPL({ messages, streamingText, toolRunning, onSubmit, onAbort, disabled }) {
|
|
31
209
|
const [input, setInput] = useState("");
|
|
32
210
|
const { stdout } = useStdout();
|
|
33
|
-
const termWidth = stdout?.columns ?? 80;
|
|
211
|
+
const termWidth = (stdout?.columns ?? 80) - 2;
|
|
34
212
|
const handleSubmit = useCallback((val) => {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
useInput((_input, key) => {
|
|
42
|
-
if (key.escape && disabled && onAbort)
|
|
43
|
-
onAbort();
|
|
44
|
-
});
|
|
213
|
+
onSubmit(val);
|
|
214
|
+
}, [onSubmit]);
|
|
215
|
+
const handleAbort = useCallback(() => {
|
|
216
|
+
onAbort?.();
|
|
217
|
+
}, [onAbort]);
|
|
218
|
+
// Scrolling: show last N messages
|
|
45
219
|
const visible = messages.slice(-MAX_VISIBLE);
|
|
46
|
-
return (_jsxs(Box, { flexDirection: "column", width:
|
|
220
|
+
return (_jsxs(Box, { flexDirection: "column", width: "100%", children: [_jsxs(Box, { flexDirection: "column", flexGrow: 1, children: [visible.map(m => _jsx(MessageLine, { msg: m }, m.id)), streamingText && (_jsxs(Box, { flexDirection: "row", gap: 1, marginTop: 1, children: [_jsx(Text, { color: AIAIAI_COLORS.muted, children: " " }), _jsx(Text, { color: AIAIAI_COLORS.header, bold: true, children: "\uD83E\uDD16 " }), _jsx(Text, { wrap: "wrap", children: streamingText })] })), toolRunning && (_jsx(Box, { flexDirection: "row", gap: 1, marginTop: 1, children: _jsxs(Text, { color: AIAIAI_COLORS.warn, children: ["\u2699 running ", toolRunning, "\u2026"] }) }))] }), _jsx(InputBox, { value: input, onChange: setInput, onSubmit: handleSubmit, disabled: !!disabled, onAbort: handleAbort })] }));
|
|
47
221
|
}
|
|
48
222
|
//# sourceMappingURL=REPL.js.map
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/tui/Sparkline.tsx — Mini ASCII sparkline chart for sidebar.
|
|
3
|
+
* Uses Unicode block characters: ▁ ▂ ▃ ▄ ▅ ▆ ▇ █
|
|
4
|
+
*/
|
|
5
|
+
import React from "react";
|
|
6
|
+
export interface SparklineProps {
|
|
7
|
+
data: number[];
|
|
8
|
+
width?: number;
|
|
9
|
+
label?: string;
|
|
10
|
+
color?: string;
|
|
11
|
+
}
|
|
12
|
+
export declare function Sparkline({ data, width, label, color }: SparklineProps): React.JSX.Element | null;
|
|
13
|
+
/** Track a rolling price history for sparkline use */
|
|
14
|
+
export declare class PriceHistory {
|
|
15
|
+
private prices;
|
|
16
|
+
private maxLength;
|
|
17
|
+
constructor(maxLength?: number);
|
|
18
|
+
push(price: number): void;
|
|
19
|
+
getData(): number[];
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=Sparkline.d.ts.map
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Text } from "ink";
|
|
3
|
+
const CHARS = "▁▂▃▄▅▆▇█";
|
|
4
|
+
export function Sparkline({ data, width = 30, label, color }) {
|
|
5
|
+
if (!data || data.length < 2)
|
|
6
|
+
return null;
|
|
7
|
+
const min = Math.min(...data);
|
|
8
|
+
const max = Math.max(...data);
|
|
9
|
+
const range = max - min || 1;
|
|
10
|
+
// Normalize and compress to width
|
|
11
|
+
const compressed = [];
|
|
12
|
+
const step = data.length / width;
|
|
13
|
+
for (let i = 0; i < width; i++) {
|
|
14
|
+
const idx = Math.floor(i * step);
|
|
15
|
+
compressed.push(data[idx]);
|
|
16
|
+
}
|
|
17
|
+
const bars = compressed.map(v => {
|
|
18
|
+
const normalized = (v - min) / range;
|
|
19
|
+
const idx = Math.min(7, Math.floor(normalized * 8));
|
|
20
|
+
return CHARS[Math.max(0, idx)];
|
|
21
|
+
}).join("");
|
|
22
|
+
const trend = data[data.length - 1] > (data[0] ?? data[data.length - 1]) ? "▲" : "▼";
|
|
23
|
+
const minStr = min < 1 ? min.toFixed(6) : min < 100 ? min.toFixed(2) : min.toLocaleString();
|
|
24
|
+
const maxStr = max < 1 ? max.toFixed(6) : max < 100 ? max.toFixed(2) : max.toLocaleString();
|
|
25
|
+
return (_jsxs(Box, { flexDirection: "column", children: [label && _jsxs(Text, { dimColor: true, children: [label, " ", trend] }), _jsx(Text, { color: color, children: bars }), _jsxs(Text, { dimColor: true, children: ["$", minStr, " \u2013 $", maxStr] })] }));
|
|
26
|
+
}
|
|
27
|
+
/** Track a rolling price history for sparkline use */
|
|
28
|
+
export class PriceHistory {
|
|
29
|
+
prices = [];
|
|
30
|
+
maxLength;
|
|
31
|
+
constructor(maxLength = 50) {
|
|
32
|
+
this.maxLength = maxLength;
|
|
33
|
+
}
|
|
34
|
+
push(price) {
|
|
35
|
+
this.prices.push(price);
|
|
36
|
+
if (this.prices.length > this.maxLength) {
|
|
37
|
+
this.prices = this.prices.slice(-this.maxLength);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
getData() {
|
|
41
|
+
return [...this.prices];
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=Sparkline.js.map
|
package/dist/tui/StatusBar.d.ts
CHANGED
|
@@ -9,6 +9,10 @@ export interface StatusBarProps {
|
|
|
9
9
|
toolRunning: string | null;
|
|
10
10
|
connected: boolean;
|
|
11
11
|
statusLine?: string | null;
|
|
12
|
+
cpu?: number;
|
|
13
|
+
ram?: number;
|
|
14
|
+
uptime?: string;
|
|
15
|
+
apiCalls?: number;
|
|
12
16
|
}
|
|
13
|
-
export declare function StatusBar({ model, chain, price, toolRunning, connected, statusLine }: StatusBarProps): React.JSX.Element;
|
|
17
|
+
export declare function StatusBar({ model, chain, price, toolRunning, connected, statusLine, cpu, ram, uptime, apiCalls }: StatusBarProps): React.JSX.Element;
|
|
14
18
|
//# sourceMappingURL=StatusBar.d.ts.map
|
package/dist/tui/StatusBar.js
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { Box, Text } from "ink";
|
|
3
3
|
import { AIAIAI_COLORS } from "./theme.js";
|
|
4
|
-
export function StatusBar({ model, chain, price, toolRunning, connected, statusLine }) {
|
|
4
|
+
export function StatusBar({ model, chain, price, toolRunning, connected, statusLine, cpu, ram, uptime, apiCalls }) {
|
|
5
5
|
const chainShort = chain.slice(0, 8);
|
|
6
|
-
const modelShort = model.split("/").pop()?.slice(0,
|
|
6
|
+
const modelShort = model.split("/").pop()?.slice(0, 16) ?? model.slice(0, 16);
|
|
7
|
+
const cpuColor = (cpu ?? 0) > 80 ? AIAIAI_COLORS.error : (cpu ?? 0) > 50 ? AIAIAI_COLORS.warn : AIAIAI_COLORS.success;
|
|
8
|
+
const ramColor = (ram ?? 0) > 85 ? AIAIAI_COLORS.error : (ram ?? 0) > 60 ? AIAIAI_COLORS.warn : AIAIAI_COLORS.success;
|
|
7
9
|
return (_jsxs(Box, { borderStyle: "single", borderColor: AIAIAI_COLORS.dim, paddingX: 1, flexDirection: "row", justifyContent: "space-between", children: [_jsxs(Box, { gap: 2, children: [_jsx(Text, { color: AIAIAI_COLORS.accent, bold: true, children: "\uD83E\uDD16 AIAIAI" }), price ? _jsx(Text, { color: AIAIAI_COLORS.success, children: price }) : null, _jsx(Text, { color: AIAIAI_COLORS.muted, children: modelShort })] }), _jsx(Box, { children: toolRunning
|
|
8
10
|
? _jsxs(Text, { color: AIAIAI_COLORS.warn, children: ["\u2699 ", toolRunning] })
|
|
9
11
|
: statusLine
|
|
10
|
-
? _jsx(Text, { color: AIAIAI_COLORS.muted, children: statusLine.slice(0,
|
|
11
|
-
: _jsx(Text, { color: AIAIAI_COLORS.muted, children: connected ? "ready" : "connecting…" }) }),
|
|
12
|
+
? _jsx(Text, { color: AIAIAI_COLORS.muted, children: statusLine.slice(0, 60) })
|
|
13
|
+
: _jsx(Text, { color: AIAIAI_COLORS.muted, children: connected ? "ready" : "connecting…" }) }), _jsxs(Box, { gap: 2, children: [cpu !== undefined && _jsxs(Text, { color: cpuColor, children: ["CPU:", cpu, "%"] }), ram !== undefined && _jsxs(Text, { color: ramColor, children: ["RAM:", ram, "%"] }), uptime && _jsx(Text, { color: AIAIAI_COLORS.muted, children: uptime }), apiCalls !== undefined && _jsxs(Text, { color: AIAIAI_COLORS.muted, children: ["API:", apiCalls, "/m"] }), _jsxs(Text, { color: AIAIAI_COLORS.header, children: ["\u26D3 ", chainShort] })] })] }));
|
|
12
14
|
}
|
|
13
15
|
//# sourceMappingURL=StatusBar.js.map
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/tui/ThemePresets.ts — Theme presets system for AIAIAI TUI.
|
|
3
|
+
* 5 built-in presets + custom via ~/.aiaiai/config/theme.json
|
|
4
|
+
*/
|
|
5
|
+
export interface ThemeColors {
|
|
6
|
+
accent: string;
|
|
7
|
+
header: string;
|
|
8
|
+
muted: string;
|
|
9
|
+
dim: string;
|
|
10
|
+
success: string;
|
|
11
|
+
warn: string;
|
|
12
|
+
error: string;
|
|
13
|
+
background: string;
|
|
14
|
+
}
|
|
15
|
+
export interface ThemePreset {
|
|
16
|
+
name: string;
|
|
17
|
+
description: string;
|
|
18
|
+
colors: ThemeColors;
|
|
19
|
+
}
|
|
20
|
+
export declare const PRESETS: Record<string, ThemePreset>;
|
|
21
|
+
export declare function getCurrentTheme(): string;
|
|
22
|
+
export declare function setTheme(name: string): boolean;
|
|
23
|
+
export declare function getPresetColors(): ThemeColors;
|
|
24
|
+
export declare function listThemes(): string;
|
|
25
|
+
//# sourceMappingURL=ThemePresets.d.ts.map
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/tui/ThemePresets.ts — Theme presets system for AIAIAI TUI.
|
|
3
|
+
* 5 built-in presets + custom via ~/.aiaiai/config/theme.json
|
|
4
|
+
*/
|
|
5
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
6
|
+
import { join } from "node:path";
|
|
7
|
+
import { homedir } from "node:os";
|
|
8
|
+
const AIAIAI_HOME = process.env.AIAIAI_HOME ?? join(homedir(), ".aiaiai");
|
|
9
|
+
export const PRESETS = {
|
|
10
|
+
"solana": {
|
|
11
|
+
name: "Solana Sunset",
|
|
12
|
+
description: "Warm gradients inspired by the Solana blockchain colors",
|
|
13
|
+
colors: {
|
|
14
|
+
accent: "#9945FF",
|
|
15
|
+
header: "#14F195",
|
|
16
|
+
muted: "#888888",
|
|
17
|
+
dim: "#444444",
|
|
18
|
+
success: "#14F195",
|
|
19
|
+
warn: "#FFD600",
|
|
20
|
+
error: "#FF4444",
|
|
21
|
+
background: "#111111",
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
"cyberpunk": {
|
|
25
|
+
name: "Cyberpunk",
|
|
26
|
+
description: "Neon pink and cyan — late night trading terminal",
|
|
27
|
+
colors: {
|
|
28
|
+
accent: "#FF00FF",
|
|
29
|
+
header: "#00FFFF",
|
|
30
|
+
muted: "#666666",
|
|
31
|
+
dim: "#333333",
|
|
32
|
+
success: "#00FF44",
|
|
33
|
+
warn: "#FFFF00",
|
|
34
|
+
error: "#FF0044",
|
|
35
|
+
background: "#0A0A0A",
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
"monochrome": {
|
|
39
|
+
name: "Monochrome",
|
|
40
|
+
description: "Clean grayscale — professional trading desk",
|
|
41
|
+
colors: {
|
|
42
|
+
accent: "#FFFFFF",
|
|
43
|
+
header: "#DDDDDD",
|
|
44
|
+
muted: "#888888",
|
|
45
|
+
dim: "#444444",
|
|
46
|
+
success: "#CCCCCC",
|
|
47
|
+
warn: "#999999",
|
|
48
|
+
error: "#FF4444",
|
|
49
|
+
background: "#111111",
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
"forest": {
|
|
53
|
+
name: "Forest",
|
|
54
|
+
description: "Calm greens — for zen trading sessions",
|
|
55
|
+
colors: {
|
|
56
|
+
accent: "#50FA7B",
|
|
57
|
+
header: "#7BFA50",
|
|
58
|
+
muted: "#6272A4",
|
|
59
|
+
dim: "#44475A",
|
|
60
|
+
success: "#50FA7B",
|
|
61
|
+
warn: "#F1FA8C",
|
|
62
|
+
error: "#FF5555",
|
|
63
|
+
background: "#1A2D1A",
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
"ocean": {
|
|
67
|
+
name: "Ocean",
|
|
68
|
+
description: "Deep blues — data-rich dashboard feel",
|
|
69
|
+
colors: {
|
|
70
|
+
accent: "#8BE9FD",
|
|
71
|
+
header: "#6272A4",
|
|
72
|
+
muted: "#6272A4",
|
|
73
|
+
dim: "#44475A",
|
|
74
|
+
success: "#50FA7B",
|
|
75
|
+
warn: "#F1FA8C",
|
|
76
|
+
error: "#FF5555",
|
|
77
|
+
background: "#0D1B2A",
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
};
|
|
81
|
+
export function getCurrentTheme() {
|
|
82
|
+
const configPath = join(AIAIAI_HOME, "config", "theme.json");
|
|
83
|
+
try {
|
|
84
|
+
if (existsSync(configPath)) {
|
|
85
|
+
const raw = readFileSync(configPath, "utf-8");
|
|
86
|
+
const config = JSON.parse(raw);
|
|
87
|
+
return config.theme || "solana";
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
catch { /* use default */ }
|
|
91
|
+
return "solana";
|
|
92
|
+
}
|
|
93
|
+
export function setTheme(name) {
|
|
94
|
+
const preset = PRESETS[name];
|
|
95
|
+
if (!preset)
|
|
96
|
+
return false;
|
|
97
|
+
const configDir = join(AIAIAI_HOME, "config");
|
|
98
|
+
const configPath = join(configDir, "theme.json");
|
|
99
|
+
try {
|
|
100
|
+
const { mkdirSync, writeFileSync } = require("node:fs");
|
|
101
|
+
if (!existsSync(configDir))
|
|
102
|
+
mkdirSync(configDir, { recursive: true });
|
|
103
|
+
writeFileSync(configPath, JSON.stringify({ theme: name, colors: preset.colors }, null, 2), "utf-8");
|
|
104
|
+
return true;
|
|
105
|
+
}
|
|
106
|
+
catch {
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
export function getPresetColors() {
|
|
111
|
+
const themeName = getCurrentTheme();
|
|
112
|
+
return PRESETS[themeName]?.colors ?? PRESETS["solana"].colors;
|
|
113
|
+
}
|
|
114
|
+
export function listThemes() {
|
|
115
|
+
return Object.entries(PRESETS).map(([key, preset]) => ` ${key === getCurrentTheme() ? "★" : " "} ${key.padEnd(14)} ${preset.description}`).join("\n");
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=ThemePresets.js.map
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/util/clipboard.ts — Copy text to system clipboard via OSC 52 escape sequences.
|
|
3
|
+
* Works in most modern terminals: iTerm2, Terminal.app, kitty, WezTerm, Alacritty.
|
|
4
|
+
*/
|
|
5
|
+
export declare function encodeOSC52(text: string): string;
|
|
6
|
+
export declare function copyToClipboard(text: string): boolean;
|
|
7
|
+
/** Get a friendly message indicating clipboard support */
|
|
8
|
+
export declare function clipboardSupported(): string;
|
|
9
|
+
//# sourceMappingURL=clipboard.d.ts.map
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/util/clipboard.ts — Copy text to system clipboard via OSC 52 escape sequences.
|
|
3
|
+
* Works in most modern terminals: iTerm2, Terminal.app, kitty, WezTerm, Alacritty.
|
|
4
|
+
*/
|
|
5
|
+
export function encodeOSC52(text) {
|
|
6
|
+
const encoded = Buffer.from(text).toString("base64");
|
|
7
|
+
return `\x1b]52;c;${encoded}\x07`;
|
|
8
|
+
}
|
|
9
|
+
export function copyToClipboard(text) {
|
|
10
|
+
try {
|
|
11
|
+
process.stdout.write(encodeOSC52(text));
|
|
12
|
+
return true;
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
/** Get a friendly message indicating clipboard support */
|
|
19
|
+
export function clipboardSupported() {
|
|
20
|
+
const term = process.env.TERM_PROGRAM ?? "";
|
|
21
|
+
const isTerminalApp = process.env.TERM?.includes("xterm") || term.includes("iTerm") || term.includes("kitty") || term.includes("Wez") || term.includes("Alacritty") || term.includes("Terminal");
|
|
22
|
+
if (isTerminalApp)
|
|
23
|
+
return "✅ Clipboard ready (OSC 52)";
|
|
24
|
+
return "⚠️ Clipboard may not be supported in this terminal";
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=clipboard.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/util/commandSuggest.ts — Levenshtein-based command suggestions.
|
|
3
|
+
* When a user types an unknown command, suggest the closest match.
|
|
4
|
+
*/
|
|
5
|
+
export declare function levenshtein(a: string, b: string): number;
|
|
6
|
+
export declare function suggestCommands(input: string, maxResults?: number): string[];
|
|
7
|
+
//# sourceMappingURL=commandSuggest.d.ts.map
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/util/commandSuggest.ts — Levenshtein-based command suggestions.
|
|
3
|
+
* When a user types an unknown command, suggest the closest match.
|
|
4
|
+
*/
|
|
5
|
+
const COMMANDS = [
|
|
6
|
+
"help", "exit", "quit", "clear",
|
|
7
|
+
"price", "news", "models", "cost", "model",
|
|
8
|
+
"wallet", "deposit", "burn", "actions", "activity", "fees",
|
|
9
|
+
"keys", "providers", "goals", "goal add", "goal done",
|
|
10
|
+
"schedule", "sessions", "resume", "memory", "update", "gmgn",
|
|
11
|
+
"token info", "token security", "token holders", "token traders",
|
|
12
|
+
"track kol", "track smartmoney", "track follow-wallet",
|
|
13
|
+
"market kline", "market trending", "market trenches", "market signal",
|
|
14
|
+
"watch", "unwatch", "watchlist", "alerts", "alert", "compare", "portfolio",
|
|
15
|
+
"diff", "explain", "copy", "theme", "status",
|
|
16
|
+
];
|
|
17
|
+
export function levenshtein(a, b) {
|
|
18
|
+
const alen = a.length, blen = b.length;
|
|
19
|
+
const matrix = [];
|
|
20
|
+
for (let i = 0; i <= alen; i++) {
|
|
21
|
+
matrix[i] = [i];
|
|
22
|
+
}
|
|
23
|
+
for (let j = 0; j <= blen; j++) {
|
|
24
|
+
matrix[0][j] = j;
|
|
25
|
+
}
|
|
26
|
+
for (let i = 1; i <= alen; i++) {
|
|
27
|
+
for (let j = 1; j <= blen; j++) {
|
|
28
|
+
matrix[i][j] = Math.min(matrix[i - 1][j] + 1, matrix[i][j - 1] + 1, matrix[i - 1][j - 1] + (a[i - 1] === b[j - 1] ? 0 : 1));
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return matrix[alen][blen];
|
|
32
|
+
}
|
|
33
|
+
export function suggestCommands(input, maxResults = 3) {
|
|
34
|
+
const normalized = input.toLowerCase().replace(/^\/+/, "");
|
|
35
|
+
if (!normalized || normalized.length < 1)
|
|
36
|
+
return [];
|
|
37
|
+
const scored = COMMANDS.map(cmd => ({
|
|
38
|
+
cmd,
|
|
39
|
+
dist: levenshtein(normalized, cmd),
|
|
40
|
+
}));
|
|
41
|
+
scored.sort((a, b) => a.dist - b.dist);
|
|
42
|
+
return scored.slice(0, maxResults).filter(s => s.dist <= 4).map(s => s.cmd);
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=commandSuggest.js.map
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/util/confirmation.ts — Confirmation prompt for destructive operations
|
|
3
|
+
*/
|
|
4
|
+
import { createInterface } from "node:readline";
|
|
5
|
+
export async function requireConfirmation(message) {
|
|
6
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
7
|
+
const answer = await new Promise((res) => {
|
|
8
|
+
rl.question(`${message} (yes/no): `, res);
|
|
9
|
+
});
|
|
10
|
+
rl.close();
|
|
11
|
+
return answer.trim().toLowerCase() === "yes" || answer.trim().toLowerCase() === "y";
|
|
12
|
+
}
|
|
13
|
+
export function isNonInteractive() {
|
|
14
|
+
return !process.stdin.isTTY || process.env.AIAIAI_YES === "1" || process.env.CI === "true";
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=confirmation.js.map
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Global error handling utilities for AIAIAI agent
|
|
3
|
+
*/
|
|
4
|
+
import { safeLog } from "./safeLog.js";
|
|
5
|
+
// Generic error handler to wrap async operations
|
|
6
|
+
export function withErrorHandling(operation, context) {
|
|
7
|
+
return operation().catch((error) => {
|
|
8
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
9
|
+
safeLog(`[${context}] ERROR: ${errorMessage}`);
|
|
10
|
+
if (error instanceof Error) {
|
|
11
|
+
safeLog(`Stack trace: ${error.stack}`);
|
|
12
|
+
}
|
|
13
|
+
throw error; // Re-throw to maintain expected behavior
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
// Enhanced logging for unhandled promise rejections
|
|
17
|
+
export function setupGlobalErrorHandlers() {
|
|
18
|
+
process.on('unhandledRejection', (reason, promise) => {
|
|
19
|
+
console.error('[UNHANDLED_REJECTION] Reason:', reason);
|
|
20
|
+
console.error('[PROMISE]', promise);
|
|
21
|
+
process.exit(1);
|
|
22
|
+
});
|
|
23
|
+
process.on('uncaughtException', (error) => {
|
|
24
|
+
console.error('[UNCAUGHT_EXCEPTION]', error);
|
|
25
|
+
process.exit(1);
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=errorHandler.js.map
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/util/logger.ts — Structured logging with levels for AIAIAI Agent
|
|
3
|
+
*/
|
|
4
|
+
export type LogLevel = 'debug' | 'info' | 'warn' | 'error';
|
|
5
|
+
export declare const logger: {
|
|
6
|
+
debug(context: string, message: string, meta?: unknown): void;
|
|
7
|
+
info(context: string, message: string, meta?: unknown): void;
|
|
8
|
+
warn(context: string, message: string, meta?: unknown): void;
|
|
9
|
+
error(context: string, message: string, meta?: unknown): void;
|
|
10
|
+
};
|
|
11
|
+
//# sourceMappingURL=logger.d.ts.map
|