@aiaiaichain/agent 0.1.3 → 0.1.4
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 +60 -25
- package/dist/core/SystemMonitor.d.ts +35 -0
- package/dist/core/SystemMonitor.js +115 -0
- package/dist/index.d.ts +7 -2
- package/dist/index.js +7 -1
- package/dist/session/SessionStore.d.ts +45 -0
- package/dist/session/SessionStore.js +123 -0
- package/dist/tools/CrossTools.d.ts +52 -0
- package/dist/tools/CrossTools.js +182 -0
- package/dist/tui/App.d.ts +4 -3
- package/dist/tui/App.js +243 -112
- package/dist/tui/REPL.d.ts +2 -1
- package/dist/tui/REPL.js +189 -15
- package/dist/tui/StatusBar.d.ts +5 -1
- package/dist/tui/StatusBar.js +6 -4
- package/dist/wallet/AgentWallet.d.ts +1 -0
- package/dist/wallet/AgentWallet.js +1 -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.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
211
|
const termWidth = stdout?.columns ?? 80;
|
|
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: termWidth, 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"] }) }))] }),
|
|
220
|
+
return (_jsxs(Box, { flexDirection: "column", width: termWidth, 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
|
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
|
|
@@ -13,6 +13,7 @@ export declare const ACTION_WALLET = "BygDYM1ZXLQNC1HXLhnd1rHZ7E5XjioqT3vPjJFfjn
|
|
|
13
13
|
export declare const DEPOSIT_WALLET = "FBMDYpG9WXKy4SgxuATQdB2sCyzHsJWPrEr45z3TgL2e";
|
|
14
14
|
export declare const SIGNER = "GmFrDZT2cdrqykgTikVdXbe8EtCgzUDM9VsDhQnwsUsG";
|
|
15
15
|
export declare const AIAIAI_MINT = "AVPJS61gZmWKtaEpb7qYPKo8Fk2xQUsayYQxPiPMpump";
|
|
16
|
+
export declare const AIAIAI_TOKEN = "AVPJS61gZmWKtaEpb7qYPKo8Fk2xQUsayYQxPiPMpump";
|
|
16
17
|
export interface WalletBalance {
|
|
17
18
|
address: string;
|
|
18
19
|
sol: number;
|
|
@@ -13,6 +13,7 @@ export const ACTION_WALLET = "BygDYM1ZXLQNC1HXLhnd1rHZ7E5XjioqT3vPjJFfjnU2";
|
|
|
13
13
|
export const DEPOSIT_WALLET = "FBMDYpG9WXKy4SgxuATQdB2sCyzHsJWPrEr45z3TgL2e";
|
|
14
14
|
export const SIGNER = "GmFrDZT2cdrqykgTikVdXbe8EtCgzUDM9VsDhQnwsUsG";
|
|
15
15
|
export const AIAIAI_MINT = "AVPJS61gZmWKtaEpb7qYPKo8Fk2xQUsayYQxPiPMpump";
|
|
16
|
+
export const AIAIAI_TOKEN = AIAIAI_MINT;
|
|
16
17
|
const USDC_MINT = "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v";
|
|
17
18
|
function getRpcUrl() {
|
|
18
19
|
return process.env.SOLANA_RPC_URL || "https://api.mainnet-beta.solana.com";
|
package/docs/COMMANDS.md
CHANGED
|
@@ -32,8 +32,8 @@
|
|
|
32
32
|
| `/help` | Show all commands |
|
|
33
33
|
| `/price` | $AIAIAI price |
|
|
34
34
|
| `/news` | Latest crypto news |
|
|
35
|
-
| `/models` | List
|
|
36
|
-
| `/model` | Switch AI model |
|
|
35
|
+
| `/models [q]` | List/search models |
|
|
36
|
+
| `/model [q]` | Switch AI model |
|
|
37
37
|
| `/cost` | Token usage cost |
|
|
38
38
|
| `/wallet` | Agent wallets |
|
|
39
39
|
| `/deposit` | Deposit instructions |
|
|
@@ -41,22 +41,53 @@
|
|
|
41
41
|
| `/actions` | Recent actions |
|
|
42
42
|
| `/fees` | Fee tracker |
|
|
43
43
|
| `/keys` | Provider management |
|
|
44
|
-
| `/
|
|
45
|
-
| `/gmgn status` | GMGN status |
|
|
46
|
-
| `/gmgn <cmd>` | GMGN sub-command |
|
|
47
|
-
| `/update` | Check for updates |
|
|
48
|
-
| `/goals` | Goal management |
|
|
44
|
+
| `/goals [add|done|list]` | Goal management |
|
|
49
45
|
| `/schedule` | Task scheduler |
|
|
50
46
|
| `/memory <q>` | Search memory |
|
|
47
|
+
| `/sessions` | List saved sessions |
|
|
48
|
+
| `/resume <n>` | Resume a session |
|
|
51
49
|
| `/clear` | Clear chat |
|
|
52
50
|
| `/exit` | Exit |
|
|
53
51
|
|
|
52
|
+
### GMGN Commands
|
|
53
|
+
|
|
54
|
+
| Command | Description |
|
|
55
|
+
|---------|-------------|
|
|
56
|
+
| `/token info --chain <c> --address <a>` | Token info |
|
|
57
|
+
| `/token security --chain <c> --address <a>` | Security audit |
|
|
58
|
+
| `/token holders --chain <c> --address <a>` | Holder list |
|
|
59
|
+
| `/token traders --chain <c> --address <a>` | Trader list |
|
|
60
|
+
| `/track kol --chain <c>` | Top KOL buys |
|
|
61
|
+
| `/track smartmoney --chain <c>` | Smart money buys |
|
|
62
|
+
| `/track follow-wallet --chain <c>` | Followed wallet buys |
|
|
63
|
+
| `/market kline --chain <c> --address <a> --resolution <1h|4h|1d>` | Candlestick chart |
|
|
64
|
+
| `/market trending --chain <c> --interval <1h|6h|24h>` | Trending tokens |
|
|
65
|
+
| `/market trenches --chain <c> --type <new|near|completed>` | Launchpad trenches |
|
|
66
|
+
| `/market signal --chain <sol|bsc>` | Buy/sell signals |
|
|
67
|
+
| `/gmgn` / `/gmgnhelp` | GMGN help |
|
|
68
|
+
| `/gmgn status` | GMGN status |
|
|
69
|
+
|
|
70
|
+
### Cross-Tool Commands
|
|
71
|
+
|
|
72
|
+
| Command | Description |
|
|
73
|
+
|---------|-------------|
|
|
74
|
+
| `/watch <address>` | Add token to watch list |
|
|
75
|
+
| `/unwatch <address>` | Remove from watch list |
|
|
76
|
+
| `/watchlist` | Show watched tokens |
|
|
77
|
+
| `/alert above <price>` | Set price alert (above) |
|
|
78
|
+
| `/alert below <price>` | Set price alert (below) |
|
|
79
|
+
| `/alerts` | List active alerts |
|
|
80
|
+
| `/compare <addr1> <addr2>` | Side-by-side token comparison |
|
|
81
|
+
| `/portfolio [address]` | Wallet portfolio analysis |
|
|
82
|
+
|
|
54
83
|
## TUI Keyboard
|
|
55
84
|
|
|
56
85
|
| Key | Action |
|
|
57
86
|
|-----|--------|
|
|
58
87
|
| `Ctrl+C` | Exit |
|
|
59
88
|
| `Escape` | Abort streaming response |
|
|
60
|
-
|
|
|
61
|
-
| `
|
|
89
|
+
| `↑` / `↓` | Command history navigation |
|
|
90
|
+
| `Tab` | Auto-complete commands |
|
|
91
|
+
| `Enter` | Submit message / command |
|
|
92
|
+
| `Shift+Enter` | New line (multi-line input) |
|
|
62
93
|
| `/` | Command prefix |
|
package/docs/README.md
CHANGED
|
@@ -9,6 +9,8 @@ AIAIAI Chain Agent is a Solana-native AI agent that runs entirely in your termin
|
|
|
9
9
|
**Chain:** Solana (primary)
|
|
10
10
|
**License:** MIT
|
|
11
11
|
|
|
12
|
+
**Links:** [X / Twitter](https://x.com/aiaiaisol) · [aiaiaichain.xyz](https://aiaiaichain.xyz)
|
|
13
|
+
|
|
12
14
|
## Installation
|
|
13
15
|
|
|
14
16
|
```bash
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aiaiaichain/agent",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"description": "AIAIAI Chain Agent — Solana-native AI agent for decentralized AI governance. Ticker: $AIAIAI",
|
|
5
5
|
"author": "AIAIAI Foundation",
|
|
6
6
|
"license": "MIT",
|
|
@@ -28,7 +28,8 @@
|
|
|
28
28
|
"start": "node dist/cli.js",
|
|
29
29
|
"type-check": "tsc --noEmit --project tsconfig.json",
|
|
30
30
|
"test": "echo \"no tests yet\" && exit 0",
|
|
31
|
-
"prepublishOnly": "npm run build"
|
|
31
|
+
"prepublishOnly": "npm run build",
|
|
32
|
+
"postinstall": "node scripts/postinstall.js"
|
|
32
33
|
},
|
|
33
34
|
"dependencies": {
|
|
34
35
|
"@sinclair/typebox": "^0.32.0",
|
|
@@ -41,7 +42,7 @@
|
|
|
41
42
|
"devDependencies": {
|
|
42
43
|
"@types/node": "^20.19.41",
|
|
43
44
|
"@types/react": "^18.3.29",
|
|
44
|
-
"typescript": "^5.
|
|
45
|
+
"typescript": "^5.10.0"
|
|
45
46
|
},
|
|
46
47
|
"engines": {
|
|
47
48
|
"node": ">=20.0.0"
|
|
@@ -58,6 +59,7 @@
|
|
|
58
59
|
"files": [
|
|
59
60
|
"dist",
|
|
60
61
|
"bin",
|
|
62
|
+
"scripts",
|
|
61
63
|
"README.md",
|
|
62
64
|
"docs",
|
|
63
65
|
"!dist/**/*.map"
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* postinstall.js — creates bin symlinks if npm didn't do it.
|
|
6
|
+
* This handles the case where `npm install -g` doesn't create
|
|
7
|
+
* symlinks for scoped packages.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { existsSync, symlinkSync, mkdirSync, readdirSync } from 'node:fs';
|
|
11
|
+
import { join, dirname } from 'node:path';
|
|
12
|
+
import { fileURLToPath } from 'node:url';
|
|
13
|
+
|
|
14
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
15
|
+
const PKG_ROOT = join(__dirname, '..');
|
|
16
|
+
const BIN_DIR = join(PKG_ROOT, 'bin');
|
|
17
|
+
|
|
18
|
+
// Only run if we're in a node_modules install (not dev)
|
|
19
|
+
if (!PKG_ROOT.includes('node_modules')) process.exit(0);
|
|
20
|
+
|
|
21
|
+
const NM_BIN = join(PKG_ROOT, 'node_modules', '.bin');
|
|
22
|
+
|
|
23
|
+
try {
|
|
24
|
+
mkdirSync(NM_BIN, { recursive: true });
|
|
25
|
+
|
|
26
|
+
const bins = readdirSync(BIN_DIR).filter(f => !f.endsWith('.map'));
|
|
27
|
+
for (const bin of bins) {
|
|
28
|
+
const src = join(BIN_DIR, bin);
|
|
29
|
+
const dst = join(NM_BIN, bin);
|
|
30
|
+
try { symlinkSync(src, dst); } catch { /* already exists */ }
|
|
31
|
+
}
|
|
32
|
+
} catch {
|
|
33
|
+
// Non-fatal — npm might have already created the links
|
|
34
|
+
}
|