balchemy 0.1.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 (67) hide show
  1. package/README.md +59 -0
  2. package/assets/bcrow.png +0 -0
  3. package/dist/agent-store.d.ts +40 -0
  4. package/dist/agent-store.d.ts.map +1 -0
  5. package/dist/agent-store.js +206 -0
  6. package/dist/agent-store.js.map +1 -0
  7. package/dist/config-loader.d.ts +8 -0
  8. package/dist/config-loader.d.ts.map +1 -0
  9. package/dist/config-loader.js +106 -0
  10. package/dist/config-loader.js.map +1 -0
  11. package/dist/docker-gen.d.ts +6 -0
  12. package/dist/docker-gen.d.ts.map +1 -0
  13. package/dist/docker-gen.js +40 -0
  14. package/dist/docker-gen.js.map +1 -0
  15. package/dist/index.d.ts +16 -0
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +143 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/openai-oauth.d.ts +28 -0
  20. package/dist/openai-oauth.d.ts.map +1 -0
  21. package/dist/openai-oauth.js +215 -0
  22. package/dist/openai-oauth.js.map +1 -0
  23. package/dist/runner.d.ts +6 -0
  24. package/dist/runner.d.ts.map +1 -0
  25. package/dist/runner.js +63 -0
  26. package/dist/runner.js.map +1 -0
  27. package/dist/terminal-logo.d.ts +15 -0
  28. package/dist/terminal-logo.d.ts.map +1 -0
  29. package/dist/terminal-logo.js +121 -0
  30. package/dist/terminal-logo.js.map +1 -0
  31. package/dist/tui/AgentBridge.d.ts +35 -0
  32. package/dist/tui/AgentBridge.d.ts.map +1 -0
  33. package/dist/tui/AgentBridge.js +235 -0
  34. package/dist/tui/AgentBridge.js.map +1 -0
  35. package/dist/tui/App.d.ts +8 -0
  36. package/dist/tui/App.d.ts.map +1 -0
  37. package/dist/tui/App.js +118 -0
  38. package/dist/tui/App.js.map +1 -0
  39. package/dist/tui/ChatAgent.d.ts +41 -0
  40. package/dist/tui/ChatAgent.d.ts.map +1 -0
  41. package/dist/tui/ChatAgent.js +312 -0
  42. package/dist/tui/ChatAgent.js.map +1 -0
  43. package/dist/tui/ChatPanel.d.ts +10 -0
  44. package/dist/tui/ChatPanel.d.ts.map +1 -0
  45. package/dist/tui/ChatPanel.js +43 -0
  46. package/dist/tui/ChatPanel.js.map +1 -0
  47. package/dist/tui/StatusPanel.d.ts +8 -0
  48. package/dist/tui/StatusPanel.d.ts.map +1 -0
  49. package/dist/tui/StatusPanel.js +25 -0
  50. package/dist/tui/StatusPanel.js.map +1 -0
  51. package/dist/tui/start.d.ts +3 -0
  52. package/dist/tui/start.d.ts.map +1 -0
  53. package/dist/tui/start.js +14 -0
  54. package/dist/tui/start.js.map +1 -0
  55. package/dist/tui/types.d.ts +61 -0
  56. package/dist/tui/types.d.ts.map +1 -0
  57. package/dist/tui/types.js +3 -0
  58. package/dist/tui/types.js.map +1 -0
  59. package/dist/wizard.d.ts +16 -0
  60. package/dist/wizard.d.ts.map +1 -0
  61. package/dist/wizard.js +716 -0
  62. package/dist/wizard.js.map +1 -0
  63. package/package.json +57 -0
  64. package/templates/.env.example +19 -0
  65. package/templates/Dockerfile +20 -0
  66. package/templates/agent.config.yaml +71 -0
  67. package/templates/docker-compose.yml +27 -0
@@ -0,0 +1,312 @@
1
+ /**
2
+ * ChatAgent — External LLM with MCP tool-calling capability.
3
+ *
4
+ * Instead of ask_bot (which uses the internal servant LLM),
5
+ * this calls the user's chosen LLM directly with the MCP tool
6
+ * definitions. The LLM can then call setup_agent, trade_command,
7
+ * etc. — exactly like Claude Desktop or OpenCode.
8
+ *
9
+ * Flow:
10
+ * User message → External LLM (with tools) → tool call?
11
+ * → Execute via MCP → feed result back → repeat until text response
12
+ */
13
+ // ── Known-safe LLM base URLs ─────────────────────────────────────────────────
14
+ const KNOWN_BASE_URLS = [
15
+ "https://api.openai.com/v1",
16
+ "https://generativelanguage.googleapis.com/v1beta/openai",
17
+ "https://api.x.ai/v1",
18
+ "https://openrouter.ai/api/v1",
19
+ ];
20
+ // ── ChatAgent ─────────────────────────────────────────────────────────────────
21
+ export class ChatAgent {
22
+ config;
23
+ mcp;
24
+ tools = [];
25
+ history = [];
26
+ replayFetch;
27
+ constructor(config, mcp, replayFetch) {
28
+ this.config = config;
29
+ this.mcp = mcp;
30
+ this.replayFetch = replayFetch;
31
+ // Warn if the LLM base URL is not a known trusted endpoint
32
+ if (config.llmBaseUrl &&
33
+ !KNOWN_BASE_URLS.some((u) => config.llmBaseUrl.startsWith(u))) {
34
+ process.stderr.write(`[ChatAgent] Warning: Custom LLM base URL detected: ${config.llmBaseUrl}. Ensure this is a trusted endpoint.\n`);
35
+ }
36
+ }
37
+ /** Fetch MCP tools and prepare system prompt. Call once on start. */
38
+ async init() {
39
+ try {
40
+ const toolsResp = await this.mcp.listTools();
41
+ this.tools = (toolsResp.tools ?? []).map((t) => ({
42
+ name: String(t.name ?? ""),
43
+ description: String(t.description ?? ""),
44
+ inputSchema: (t.inputSchema ?? { type: "object", properties: {} }),
45
+ }));
46
+ }
47
+ catch {
48
+ this.tools = [];
49
+ }
50
+ this.history = [{
51
+ role: "system",
52
+ content: SYSTEM_PROMPT,
53
+ }];
54
+ }
55
+ /**
56
+ * Send a user message, let the LLM respond and call tools as needed.
57
+ * Returns the final text response.
58
+ * onToolCall is fired each time the LLM calls a tool (for UI display).
59
+ */
60
+ async chat(userMessage, onToolCall) {
61
+ this.history.push({ role: "user", content: userMessage });
62
+ // Loop: call LLM → if tool calls, execute them → feed back → repeat
63
+ const MAX_ROUNDS = 10;
64
+ for (let round = 0; round < MAX_ROUNDS; round++) {
65
+ const response = await this.callLlm();
66
+ if (!response.toolCalls || response.toolCalls.length === 0) {
67
+ // Pure text response — done
68
+ this.history.push({ role: "assistant", content: response.text });
69
+ return response.text;
70
+ }
71
+ // LLM wants to call tools
72
+ this.history.push({
73
+ role: "assistant",
74
+ content: response.text || "",
75
+ tool_calls: response.toolCalls,
76
+ });
77
+ // Execute each tool call
78
+ for (const tc of response.toolCalls) {
79
+ let args;
80
+ try {
81
+ args = JSON.parse(tc.function.arguments);
82
+ }
83
+ catch {
84
+ args = {};
85
+ }
86
+ let resultText;
87
+ try {
88
+ const toolResp = await this.mcp.callTool(tc.function.name, args);
89
+ const content = toolResp.content ?? [];
90
+ const textPart = content.find((c) => c.type === "text");
91
+ resultText = textPart?.text ?? JSON.stringify(toolResp);
92
+ }
93
+ catch (err) {
94
+ resultText = `Error: ${err instanceof Error ? err.message : String(err)}`;
95
+ }
96
+ onToolCall?.(tc.function.name, resultText);
97
+ this.history.push({
98
+ role: "tool",
99
+ content: resultText,
100
+ tool_call_id: tc.id,
101
+ });
102
+ }
103
+ }
104
+ return "I hit the tool-call limit. Please try a simpler request.";
105
+ }
106
+ // ── LLM Call ──────────────────────────────────────────────────────────────
107
+ async callLlm() {
108
+ if (this.config.llmProvider === "anthropic") {
109
+ return this.callAnthropic();
110
+ }
111
+ return this.callOpenAi();
112
+ }
113
+ async callOpenAi() {
114
+ const baseUrl = (this.config.llmBaseUrl ?? "https://api.openai.com/v1").replace(/\/+$/, "");
115
+ const controller = new AbortController();
116
+ const timer = setTimeout(() => controller.abort(), this.config.llmTimeoutMs ?? 30_000);
117
+ try {
118
+ const body = {
119
+ model: this.config.llmModel ?? "gpt-5.4-mini",
120
+ messages: this.history,
121
+ max_completion_tokens: 2048,
122
+ store: false,
123
+ };
124
+ if (this.tools.length > 0) {
125
+ body.tools = this.tools.map((t) => ({
126
+ type: "function",
127
+ function: {
128
+ name: t.name,
129
+ description: t.description,
130
+ parameters: t.inputSchema,
131
+ },
132
+ }));
133
+ }
134
+ const res = await fetch(`${baseUrl}/chat/completions`, {
135
+ method: "POST",
136
+ headers: {
137
+ "Content-Type": "application/json",
138
+ Authorization: `Bearer ${this.config.llmApiKey}`,
139
+ },
140
+ body: JSON.stringify(body),
141
+ signal: controller.signal,
142
+ });
143
+ if (!res.ok) {
144
+ const errText = await res.text();
145
+ throw new Error(`LLM API ${res.status}: ${errText.slice(0, 200)}`);
146
+ }
147
+ const data = await res.json();
148
+ const msg = data.choices[0]?.message;
149
+ return {
150
+ text: msg?.content ?? "",
151
+ toolCalls: msg?.tool_calls,
152
+ };
153
+ }
154
+ finally {
155
+ clearTimeout(timer);
156
+ }
157
+ }
158
+ async callAnthropic() {
159
+ const controller = new AbortController();
160
+ const timer = setTimeout(() => controller.abort(), this.config.llmTimeoutMs ?? 30_000);
161
+ try {
162
+ // Separate system message
163
+ const systemMsg = this.history.find((m) => m.role === "system");
164
+ const anthropicMsgs = [];
165
+ for (const m of this.history) {
166
+ if (m.role === "system")
167
+ continue;
168
+ if (m.role === "tool") {
169
+ // Tool result → wrap in user message with tool_result block.
170
+ // Anthropic requires tool_result blocks to immediately follow the
171
+ // assistant message that invoked the tool. If the previous message
172
+ // is already a user with tool_result blocks, merge into it.
173
+ const resultBlock = {
174
+ type: "tool_result",
175
+ tool_use_id: m.tool_call_id ?? "",
176
+ content: m.content,
177
+ };
178
+ const prev = anthropicMsgs[anthropicMsgs.length - 1];
179
+ if (prev?.role === "user" && Array.isArray(prev.content)) {
180
+ prev.content.push(resultBlock);
181
+ }
182
+ else {
183
+ anthropicMsgs.push({ role: "user", content: [resultBlock] });
184
+ }
185
+ continue;
186
+ }
187
+ if (m.role === "assistant" && m.tool_calls?.length) {
188
+ // Assistant message with tool calls → native tool_use blocks
189
+ const blocks = [];
190
+ if (m.content) {
191
+ blocks.push({ type: "text", text: m.content });
192
+ }
193
+ for (const tc of m.tool_calls) {
194
+ let input;
195
+ try {
196
+ input = JSON.parse(tc.function.arguments);
197
+ }
198
+ catch {
199
+ input = {};
200
+ }
201
+ blocks.push({ type: "tool_use", id: tc.id, name: tc.function.name, input });
202
+ }
203
+ anthropicMsgs.push({ role: "assistant", content: blocks });
204
+ continue;
205
+ }
206
+ // Regular user or assistant message
207
+ anthropicMsgs.push({ role: m.role, content: m.content });
208
+ }
209
+ const body = {
210
+ model: this.config.llmModel ?? "claude-haiku-4-5-20251001",
211
+ max_tokens: 2048,
212
+ messages: anthropicMsgs,
213
+ };
214
+ if (systemMsg)
215
+ body.system = systemMsg.content;
216
+ if (this.tools.length > 0) {
217
+ body.tools = this.tools.map((t) => ({
218
+ name: t.name,
219
+ description: t.description,
220
+ input_schema: t.inputSchema,
221
+ }));
222
+ }
223
+ const res = await fetch("https://api.anthropic.com/v1/messages", {
224
+ method: "POST",
225
+ headers: {
226
+ "Content-Type": "application/json",
227
+ "x-api-key": this.config.llmApiKey,
228
+ "anthropic-version": "2023-06-01",
229
+ },
230
+ body: JSON.stringify(body),
231
+ signal: controller.signal,
232
+ });
233
+ if (!res.ok) {
234
+ const errText = await res.text();
235
+ throw new Error(`Anthropic API ${res.status}: ${errText.slice(0, 200)}`);
236
+ }
237
+ const data = await res.json();
238
+ const textParts = data.content.filter((c) => c.type === "text");
239
+ const toolParts = data.content.filter((c) => c.type === "tool_use");
240
+ const toolCalls = toolParts.length > 0
241
+ ? toolParts.map((tc) => ({
242
+ id: tc.id,
243
+ type: "function",
244
+ function: { name: tc.name, arguments: JSON.stringify(tc.input) },
245
+ }))
246
+ : undefined;
247
+ return {
248
+ text: textParts.map((t) => t.text).join("\n"),
249
+ toolCalls,
250
+ };
251
+ }
252
+ finally {
253
+ clearTimeout(timer);
254
+ }
255
+ }
256
+ }
257
+ // ── System Prompt ─────────────────────────────────────────────────────────────
258
+ const SYSTEM_PROMPT = `You are a Balchemy autonomous trading agent. You help the user set up and run their crypto trading bot on Solana and Base chains.
259
+
260
+ You have access to MCP tools via tool calling. Always call tools when you need to take action — never just describe what you would do.
261
+
262
+ ## SETUP FLOW
263
+
264
+ When setup is incomplete (check with setup_agent action="get_status"), follow these steps IN ORDER. Do NOT skip steps. Ask the user questions between steps.
265
+
266
+ ### Step 1: Bind developer wallet
267
+ - Ask the user: "What is your EVM wallet address? This will be your recovery wallet."
268
+ - Wait for their answer. They must give you a 0x... address.
269
+ - Call: setup_agent { action: "bind_developer_wallet", walletAddress: "<their address>", walletAddressConfirm: "<their address>" }
270
+ - Tell them their master key from the response — this is critical, they must save it.
271
+
272
+ ### Step 2: Create trading wallets
273
+ - Tell the user you're creating their trading wallets.
274
+ - Call: setup_agent { action: "create_wallet", chain: "solana" }
275
+ - Call: setup_agent { action: "create_wallet", chain: "base" }
276
+ - Show them both wallet addresses clearly.
277
+ - Tell them: "Fund your Solana wallet with at least 0.05 SOL to start trading."
278
+
279
+ ### Step 3: Configure slippage
280
+ - Ask: "What slippage tolerance do you want? Default is 2% (200 basis points). Memecoin trading usually needs 3-5%."
281
+ - Wait for their answer. Use their preference.
282
+ - Call: setup_agent { action: "configure_slippage", slippageBps: <their choice or 200> }
283
+
284
+ ### Step 4: Configure trading strategy
285
+ - Ask: "Describe your trading strategy in natural language. For example: 'Trade new PumpFun launches with max 0.01 SOL per trade, stop loss at 20%, take profit at 100%. Max 1 position at a time.'"
286
+ - Wait for their answer. This is the most important step.
287
+ - Call: setup_agent { action: "configure_autonomous", shadowMode: false, naturalLanguageRules: "<their exact words>" }
288
+ - NEVER set shadowMode to true. All trading is LIVE.
289
+ - Confirm back to them: "Your strategy is configured. Here's what I understood: [summary]"
290
+
291
+ ### Step 5: Done
292
+ - Tell them setup is complete. Show a summary: wallets, strategy, slippage.
293
+ - Tell them you're now listening for events and ready to trade.
294
+
295
+ ## IMPORTANT RULES
296
+ - shadowMode is ALWAYS false. Never enable it.
297
+ - Complete ALL setup steps before trading.
298
+ - Always show wallet addresses and master key to the user.
299
+ - Ask questions and wait for answers — don't rush through setup.
300
+ - When the user tells you their strategy, repeat it back to confirm before configuring.
301
+
302
+ ## TRADING BEHAVIOR (after setup)
303
+ - Explain every decision: what token you found, why it matches their strategy, what you're doing.
304
+ - Keep it to 1-3 sentences per decision.
305
+ - Show amounts in SOL.
306
+ - Respect the user's rules at all times.
307
+
308
+ ## LANGUAGE
309
+ Respond in the same language the user writes in. Turkish input → Turkish response. English → English.
310
+
311
+ Be direct. Don't be verbose. Don't add unnecessary pleasantries.`;
312
+ //# sourceMappingURL=ChatAgent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChatAgent.js","sourceRoot":"","sources":["../../src/tui/ChatAgent.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import React from "react";
2
+ import type { ChatMessage } from "./types.js";
3
+ interface ChatPanelProps {
4
+ messages: ChatMessage[];
5
+ onSend: (text: string) => void;
6
+ inputActive: boolean;
7
+ }
8
+ export declare function ChatPanel({ messages, onSend, inputActive }: ChatPanelProps): React.ReactElement;
9
+ export {};
10
+ //# sourceMappingURL=ChatPanel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChatPanel.d.ts","sourceRoot":"","sources":["../../src/tui/ChatPanel.tsx"],"names":[],"mappings":"AACA,OAAO,KAAgC,MAAM,OAAO,CAAC;AAGrD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAoC9C,UAAU,cAAc;IACtB,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,WAAW,EAAE,OAAO,CAAC;CACtB;AAED,wBAAgB,SAAS,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,EAAE,cAAc,GAAG,KAAK,CAAC,YAAY,CAqC/F"}
@@ -0,0 +1,43 @@
1
+ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
+ // src/tui/ChatPanel.tsx
3
+ import { useState, useCallback } from "react";
4
+ import { Box, Text } from "ink";
5
+ import { TextInput } from "@inkjs/ui";
6
+ const MESSAGE_ICONS = {
7
+ agent: "[bot]",
8
+ user: "[you]",
9
+ system: "[sys]",
10
+ trade: "[txn]",
11
+ error: "[err]",
12
+ };
13
+ const MESSAGE_COLORS = {
14
+ agent: "cyan",
15
+ user: "white",
16
+ system: "gray",
17
+ trade: "green",
18
+ error: "red",
19
+ };
20
+ function MessageLine({ msg }) {
21
+ const icon = MESSAGE_ICONS[msg.type] ?? ".";
22
+ const color = MESSAGE_COLORS[msg.type] ?? "white";
23
+ const time = new Date(msg.timestamp).toLocaleTimeString("en-GB", {
24
+ hour: "2-digit",
25
+ minute: "2-digit",
26
+ second: "2-digit",
27
+ });
28
+ return (_jsxs(Box, { children: [_jsxs(Text, { dimColor: true, children: [time, " "] }), _jsxs(Text, { children: [icon, " "] }), _jsx(Text, { color: color, wrap: "wrap", children: msg.text })] }));
29
+ }
30
+ export function ChatPanel({ messages, onSend, inputActive }) {
31
+ // Show last N messages that fit the terminal
32
+ const visibleMessages = messages.slice(-100);
33
+ const [inputKey, setInputKey] = useState(0);
34
+ const handleSubmit = useCallback((value) => {
35
+ if (value.trim()) {
36
+ onSend(value.trim());
37
+ // Force re-mount TextInput to clear it
38
+ setInputKey((k) => k + 1);
39
+ }
40
+ }, [onSend]);
41
+ return (_jsxs(Box, { flexDirection: "column", flexGrow: 1, children: [_jsx(Box, { flexDirection: "column", flexGrow: 1, overflowY: "hidden", children: visibleMessages.map((msg) => (_jsx(MessageLine, { msg: msg }, msg.id))) }), _jsxs(Box, { borderStyle: "single", borderColor: "cyan", borderTop: true, borderBottom: false, borderLeft: false, borderRight: false, children: [_jsx(Text, { color: "cyan", children: "> " }), inputActive ? (_jsx(TextInput, { placeholder: "Type a message...", onSubmit: handleSubmit }, inputKey)) : (_jsx(Text, { dimColor: true, children: "Connecting..." }))] })] }));
42
+ }
43
+ //# sourceMappingURL=ChatPanel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChatPanel.js","sourceRoot":"","sources":["../../src/tui/ChatPanel.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import React from "react";
2
+ import type { StatusData } from "./types.js";
3
+ interface StatusPanelProps {
4
+ status: StatusData;
5
+ }
6
+ export declare function StatusPanel({ status }: StatusPanelProps): React.ReactElement;
7
+ export {};
8
+ //# sourceMappingURL=StatusPanel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StatusPanel.d.ts","sourceRoot":"","sources":["../../src/tui/StatusPanel.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AA4B7C,UAAU,gBAAgB;IACxB,MAAM,EAAE,UAAU,CAAC;CACpB;AAED,wBAAgB,WAAW,CAAC,EAAE,MAAM,EAAE,EAAE,gBAAgB,GAAG,KAAK,CAAC,YAAY,CAoE5E"}
@@ -0,0 +1,25 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box, Text } from "ink";
3
+ function Section({ title, children }) {
4
+ return (_jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsx(Text, { bold: true, dimColor: true, children: title }), children] }));
5
+ }
6
+ function truncate(s, len) {
7
+ return s.length > len ? s.slice(0, len - 2) + ".." : s;
8
+ }
9
+ function formatSol(n) {
10
+ return n.toFixed(4);
11
+ }
12
+ function formatUptime(ms) {
13
+ const s = Math.floor(ms / 1000);
14
+ const m = Math.floor(s / 60);
15
+ const h = Math.floor(m / 60);
16
+ if (h > 0)
17
+ return `${h}h ${m % 60}m`;
18
+ if (m > 0)
19
+ return `${m}m ${s % 60}s`;
20
+ return `${s}s`;
21
+ }
22
+ export function StatusPanel({ status }) {
23
+ return (_jsxs(Box, { flexDirection: "column", width: 26, borderStyle: "single", borderColor: "gray", paddingX: 1, children: [_jsxs(Section, { title: "Balance", children: [_jsxs(Text, { color: "green", bold: true, children: [formatSol(status.balanceSol), " SOL"] }), _jsxs(Text, { dimColor: true, children: ["~$", status.balanceUsd.toFixed(2)] })] }), _jsxs(Section, { title: "Wallets", children: [status.wallets.map((w) => (_jsxs(Text, { dimColor: true, children: [w.chain === "solana" ? "SOL" : "EVM", ": ", truncate(w.address, 16)] }, w.chain))), status.wallets.length === 0 && _jsx(Text, { dimColor: true, children: "No wallets" })] }), _jsxs(Section, { title: "Active Trades", children: [status.activeTrades.length === 0 && _jsx(Text, { dimColor: true, children: "None" }), status.activeTrades.slice(0, 5).map((t, i) => (_jsx(Box, { children: _jsxs(Text, { color: t.action === "buy" ? "green" : "red", children: [truncate(t.token, 10), " ", t.amount] }) }, `${t.token}-${i}`)))] }), _jsxs(Section, { title: "Recent", children: [status.recentTools.length === 0 && _jsx(Text, { dimColor: true, children: "No calls yet" }), status.recentTools.slice(-5).map((t, i) => (_jsxs(Text, { dimColor: true, children: [t.success ? "+" : "x", " ", truncate(t.name, 12), " ", t.durationMs, "ms"] }, `${t.name}-${i}`)))] }), _jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsxs(Text, { dimColor: true, children: [status.sseConnected ? "*" : "o", " ", status.status, " | ", formatUptime(status.uptime)] }), _jsxs(Text, { dimColor: true, children: [status.eventsReceived, " events | ", status.tradesExecuted, " trades"] }), _jsxs(Text, { dimColor: true, children: ["LLM: $", status.llmCostToday.toFixed(4), " / $", status.maxDailyLlmCost] })] }), _jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Text, { bold: true, dimColor: true, children: "Commands" }), _jsx(Text, { dimColor: true, children: "/stop /new /switch" }), _jsx(Text, { dimColor: true, children: "/clear /help" })] })] }));
24
+ }
25
+ //# sourceMappingURL=StatusPanel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StatusPanel.js","sourceRoot":"","sources":["../../src/tui/StatusPanel.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { TuiConfig } from "./types.js";
2
+ export declare function startTui(config: TuiConfig): Promise<void>;
3
+ //# sourceMappingURL=start.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"start.d.ts","sourceRoot":"","sources":["../../src/tui/start.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C,wBAAsB,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAW/D"}
@@ -0,0 +1,14 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { render } from "ink";
3
+ import { App } from "./App.js";
4
+ export async function startTui(config) {
5
+ const { waitUntilExit } = render(_jsx(App, { config: config }));
6
+ // Handle SIGINT/SIGTERM gracefully
7
+ const shutdown = () => {
8
+ process.exit(0);
9
+ };
10
+ process.on("SIGINT", shutdown);
11
+ process.on("SIGTERM", shutdown);
12
+ await waitUntilExit();
13
+ }
14
+ //# sourceMappingURL=start.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"start.js","sourceRoot":"","sources":["../../src/tui/start.tsx"],"names":[],"mappings":";AAEA,OAAO,EAAE,MAAM,EAAE,MAAM,KAAK,CAAC;AAC7B,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAG/B,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,MAAiB;IAC9C,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,CAAC,KAAC,GAAG,IAAC,MAAM,EAAE,MAAM,GAAI,CAAC,CAAC;IAE1D,mCAAmC;IACnC,MAAM,QAAQ,GAAG,GAAS,EAAE;QAC1B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC;IACF,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAC/B,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IAEhC,MAAM,aAAa,EAAE,CAAC;AACxB,CAAC"}
@@ -0,0 +1,61 @@
1
+ export type MessageType = "agent" | "user" | "system" | "trade" | "error";
2
+ export interface ChatMessage {
3
+ id: string;
4
+ type: MessageType;
5
+ text: string;
6
+ timestamp: number;
7
+ /** For trade messages: token address */
8
+ token?: string;
9
+ /** For trade messages: buy/sell */
10
+ action?: "buy" | "sell";
11
+ /** For trade messages: SOL amount */
12
+ amount?: string;
13
+ }
14
+ export interface TradeInfo {
15
+ token: string;
16
+ action: "buy" | "sell";
17
+ amount: string;
18
+ entryPrice?: number;
19
+ currentPricePct?: number;
20
+ txSignature?: string;
21
+ timestamp: number;
22
+ }
23
+ export interface WalletInfo {
24
+ chain: "solana" | "base";
25
+ address: string;
26
+ }
27
+ export interface ToolCall {
28
+ name: string;
29
+ durationMs: number;
30
+ success: boolean;
31
+ timestamp: number;
32
+ }
33
+ export interface StatusData {
34
+ balanceSol: number;
35
+ balanceUsd: number;
36
+ wallets: WalletInfo[];
37
+ activeTrades: TradeInfo[];
38
+ recentTools: ToolCall[];
39
+ eventsReceived: number;
40
+ decisionsExecuted: number;
41
+ tradesExecuted: number;
42
+ llmCostToday: number;
43
+ maxDailyLlmCost: number;
44
+ uptime: number;
45
+ sseConnected: boolean;
46
+ status: string;
47
+ }
48
+ export interface TuiConfig {
49
+ mcpEndpoint: string;
50
+ apiKey: string;
51
+ llmProvider: "anthropic" | "openai";
52
+ llmApiKey: string;
53
+ llmModel?: string;
54
+ llmBaseUrl?: string;
55
+ maxDailyLlmCost?: number;
56
+ llmTimeoutMs?: number;
57
+ publicId: string;
58
+ strategy: string;
59
+ shadowMode: boolean;
60
+ }
61
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/tui/types.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,MAAM,GAAG,QAAQ,GAAG,OAAO,GAAG,OAAO,CAAC;AAE1E,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,WAAW,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,wCAAwC;IACxC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,mCAAmC;IACnC,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;IACxB,qCAAqC;IACrC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,KAAK,GAAG,MAAM,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,QAAQ,GAAG,MAAM,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,UAAU;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,YAAY,EAAE,SAAS,EAAE,CAAC;IAC1B,WAAW,EAAE,QAAQ,EAAE,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,OAAO,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,SAAS;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,WAAW,GAAG,QAAQ,CAAC;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,OAAO,CAAC;CACrB"}
@@ -0,0 +1,3 @@
1
+ // src/tui/types.ts
2
+ export {};
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/tui/types.ts"],"names":[],"mappings":"AAAA,mBAAmB"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Balchemy Agent Setup Wizard
3
+ *
4
+ * Full onboarding flow:
5
+ * 1. BCrow welcome + LLM requirement notice
6
+ * 2. LLM provider selection (Anthropic, OpenAI, Gemini, Grok, OpenRouter)
7
+ * 3. API key input
8
+ * 4. Model selection (per-provider model list)
9
+ * 5. New agent or existing agent
10
+ * 6. Walletless onboarding (auto) or MCP endpoint entry
11
+ * 7. MCP setup_agent wizard (wallets, slippage, autonomous strategy)
12
+ * 8. Write agent.config.yaml + .env
13
+ * 9. Offer to start the agent loop
14
+ */
15
+ export declare function runWizard(outDir: string): Promise<void>;
16
+ //# sourceMappingURL=wizard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wizard.d.ts","sourceRoot":"","sources":["../src/wizard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAgeH,wBAAsB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAyV7D"}