nanosolana 1.0.1 → 1.0.2

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/CHANGELOG.md CHANGED
@@ -2,6 +2,12 @@
2
2
 
3
3
  All notable changes to NanoSolana will be documented in this file.
4
4
 
5
+ ## [1.0.2] — 2026-03-16
6
+
7
+ ### Fixed
8
+
9
+ - Aligned the CLI-reported version with the published npm package so `npx nanosolana --version` matches the release installed by `npx nanosolana go`.
10
+
5
11
  ## [1.0.1] — 2026-03-16
6
12
 
7
13
  ### Fixed
package/dist/cli/entry.js CHANGED
@@ -28,82 +28,177 @@ import chalk2 from "chalk";
28
28
  // src/cli/animations.ts
29
29
  import chalk from "chalk";
30
30
  import spinners from "unicode-animations";
31
- function createSpinner(msg, name = "braille") {
32
- const { frames, interval } = spinners[name];
33
- let i = 0;
34
- let text = msg;
35
- const timer = setInterval(() => {
36
- process.stdout.write(
37
- `\r\x1B[2K ${chalk.cyan(frames[i++ % frames.length])} ${chalk.white(text)}`
38
- );
39
- }, interval);
40
- return {
41
- update(newMsg) {
42
- text = newMsg;
43
- },
44
- stop(doneMsg) {
45
- clearInterval(timer);
46
- process.stdout.write(`\r\x1B[2K ${chalk.green("\u2713")} ${chalk.white(doneMsg)}
47
- `);
48
- },
49
- fail(errMsg) {
50
- clearInterval(timer);
51
- process.stdout.write(`\r\x1B[2K ${chalk.red("\u2717")} ${chalk.red(errMsg)}
31
+ var ESC = "\x1B";
32
+ var CLEAR_LINE = `\r${ESC}[2K`;
33
+ var HIDE_CURSOR = `${ESC}[?25l`;
34
+ var SHOW_CURSOR = `${ESC}[?25h`;
35
+ var CLEAR_SCREEN = `${ESC}[2J`;
36
+ var HOME = `${ESC}[H`;
37
+ var SAVE_CURSOR = `${ESC}7`;
38
+ var RESTORE_CURSOR = `${ESC}8`;
39
+ function cursorUp(n) {
40
+ return `${ESC}[${n}A`;
41
+ }
42
+ function moveTo(row, col) {
43
+ return `${ESC}[${row};${col}H`;
44
+ }
45
+ function clearLineAt(row) {
46
+ return `${moveTo(row, 1)}${ESC}[2K`;
47
+ }
48
+ var SOL_GREEN = "#14F195";
49
+ var SOL_PURPLE = "#9945FF";
50
+ var NANO_CYAN = "#00E5FF";
51
+ var NANO_GOLD = "#FFD700";
52
+ var NANO_BLUE = "#4FC3F7";
53
+ var DIM_GREEN = "#0A7B4A";
54
+ var GRADIENT_COLORS = [
55
+ "#14F195",
56
+ "#12E08A",
57
+ "#10CF7F",
58
+ "#0EBE74",
59
+ "#0CAD69",
60
+ "#0A9C5E",
61
+ "#088B53",
62
+ "#067A48"
63
+ ];
64
+ var SOLANA_GRADIENT = [
65
+ "#14F195",
66
+ "#1EE5A0",
67
+ "#28D9AB",
68
+ "#32CDB6",
69
+ "#3CC1C1",
70
+ "#46B5CC",
71
+ "#50A9D7",
72
+ "#5A9DE2",
73
+ "#6491ED",
74
+ "#6E85F8",
75
+ "#7879FF",
76
+ "#826DFF",
77
+ "#8C61FF",
78
+ "#9945FF"
79
+ ];
80
+ function sleep(ms) {
81
+ return new Promise((resolve) => setTimeout(resolve, ms));
82
+ }
83
+ function gradientText(text, colors) {
84
+ let result = "";
85
+ for (let i = 0; i < text.length; i++) {
86
+ const colorIdx = Math.floor(i / text.length * colors.length);
87
+ result += chalk.hex(colors[Math.min(colorIdx, colors.length - 1)])(text[i]);
88
+ }
89
+ return result;
90
+ }
91
+ function progressBar(percent, width = 30) {
92
+ const filled = Math.round(width * percent);
93
+ const empty = width - filled;
94
+ const bar = chalk.hex(SOL_GREEN)("\u2588".repeat(filled)) + chalk.hex(DIM_GREEN)("\u2591".repeat(empty));
95
+ const pct = chalk.hex(SOL_GREEN)(`${Math.round(percent * 100)}%`);
96
+ return `${bar} ${pct}`;
97
+ }
98
+ var NANO_BANNER = [
99
+ " \u2588\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2557 ",
100
+ " \u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557",
101
+ " \u2588\u2588\u2554\u2588\u2588\u2557 \u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2554\u2588\u2588\u2557 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2554\u2588\u2588\u2557 \u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551",
102
+ " \u2588\u2588\u2551\u255A\u2588\u2588\u2557\u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2551\u2588\u2588\u2551\u255A\u2588\u2588\u2557\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u255A\u2550\u2550\u2550\u2550\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2551\u2588\u2588\u2551\u255A\u2588\u2588\u2557\u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2551",
103
+ " \u2588\u2588\u2551 \u255A\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u255A\u2588\u2588\u2588\u2588\u2551\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u255A\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551",
104
+ " \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u2550\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D"
105
+ ];
106
+ async function printSplashBanner() {
107
+ console.log();
108
+ for (let i = 0; i < NANO_BANNER.length; i++) {
109
+ const line = NANO_BANNER[i];
110
+ console.log(gradientText(line, SOLANA_GRADIENT));
111
+ await sleep(40);
112
+ }
113
+ console.log();
114
+ const subtitle = " \u{1F99E} Autonomous Financial Intelligence on Solana";
115
+ for (let i = 0; i <= subtitle.length; i++) {
116
+ process.stdout.write(`${CLEAR_LINE}${chalk.hex(SOL_GREEN)(subtitle.slice(0, i))}${chalk.hex(DIM_GREEN)("\u258C")}`);
117
+ await sleep(12);
118
+ }
119
+ process.stdout.write(`${CLEAR_LINE}${chalk.hex(SOL_GREEN)(subtitle)}
52
120
  `);
53
- }
54
- };
121
+ console.log(chalk.gray(" OODA Trading \xB7 ClawVault Memory \xB7 TamaGOchi Pet \xB7 Mesh Network\n"));
122
+ const cols = process.stdout.columns || 80;
123
+ const dividerWidth = Math.min(cols - 4, 88);
124
+ for (let i = 0; i <= dividerWidth; i++) {
125
+ const filled = chalk.hex(SOL_GREEN)("\u2501".repeat(i));
126
+ const rest = chalk.hex(DIM_GREEN)("\u2500".repeat(dividerWidth - i));
127
+ process.stdout.write(`\r ${filled}${rest}`);
128
+ await sleep(3);
129
+ }
130
+ console.log();
55
131
  }
56
- async function runWithSpinner(label, fn, name = "braille") {
57
- const s = createSpinner(label, name);
58
- try {
59
- const result = await fn();
60
- s.stop(label);
61
- return result;
62
- } catch (err) {
63
- s.fail(`${label} \u2014 ${err.message}`);
64
- throw err;
132
+ var PHASE_ICONS = {
133
+ init: "\u2699",
134
+ birth: "\u{1F511}",
135
+ memory: "\u{1F9E0}",
136
+ pet: "\u{1F43E}",
137
+ trade: "\u{1F4CA}",
138
+ gateway: "\u{1F310}",
139
+ scan: "\u{1F50D}",
140
+ pay: "\u{1F4B3}",
141
+ register: "\u{1F4CB}",
142
+ mesh: "\u{1F578}",
143
+ complete: "\u{1F680}"
144
+ };
145
+ async function phaseTransition(phaseName, label) {
146
+ const icon = PHASE_ICONS[phaseName] ?? "\u25B8";
147
+ const cols = process.stdout.columns || 80;
148
+ const lineW = Math.min(cols - 4, 60);
149
+ console.log();
150
+ const header = `${icon} ${label}`;
151
+ process.stdout.write(` ${chalk.hex(SOL_PURPLE).bold(header)} `);
152
+ const barStart = header.length + 4;
153
+ const barLen = Math.max(0, lineW - barStart);
154
+ for (let i = 0; i < barLen; i++) {
155
+ const color = SOLANA_GRADIENT[Math.floor(i / barLen * SOLANA_GRADIENT.length)];
156
+ process.stdout.write(chalk.hex(color)("\u2500"));
157
+ if (i % 4 === 0) await sleep(2);
65
158
  }
159
+ console.log();
160
+ console.log();
66
161
  }
67
162
  var LOBSTER_FRAMES = [
68
163
  [
69
- " \u2571\u2572 \u2571\u2572 ",
70
- " \u2571 \u2572\u2500\u2500\u2571 \u2572 ",
71
- " \u2502 \u25C9 \u25C9 \u2502 ",
72
- " \u2502 \u2572\u2571 \u2502 ",
73
- " \u2572 \u2502\u2502\u2502 \u2571 ",
74
- " \u2572\u2550\u2567\u2567\u2550\u2571 ",
75
- " \u2571\u2571\u2571 \u2572\u2572\u2572 ",
76
- " \u2571\u2571\u2571 \u2572\u2572\u2572 "
164
+ " \u2571\u2572 \u2571\u2572 ",
165
+ " \u2571 \u2572\u2500\u2500\u2571 \u2572 ",
166
+ " \u2502 \u25C9 \u25C9 \u2502 ",
167
+ " \u2502 \u2572\u2571 \u2502 ",
168
+ " \u2572 \u2502\u2502\u2502 \u2571 ",
169
+ " \u2572\u2550\u2567\u2567\u2550\u2571 ",
170
+ " \u2571\u2571\u2571 \u2572\u2572\u2572 ",
171
+ " \u2571\u2571\u2571 \u2572\u2572\u2572 "
77
172
  ],
78
173
  [
79
- " \u2571\u2572 \u2571\u2572 ",
80
- " \u2571 \u2572\u2500\u2500\u2500\u2500\u2571 \u2572 ",
81
- " \u2502 \u25CF \u25CF \u2502 ",
82
- " \u2502 \u2500\u2500 \u2502 ",
83
- " \u2572 \u2502\u2502\u2502 \u2571 ",
84
- " \u2572\u2550\u2567\u2567\u2550\u2571 ",
85
- " \u2571\u2571\u2571\u2571 \u2572\u2572\u2572\u2572 ",
86
- " \u2571\u2571\u2571\u2571 \u2572\u2572\u2572\u2572 "
174
+ " \u2571\u2572 \u2571\u2572 ",
175
+ " \u2571 \u2572\u2500\u2500\u2500\u2500\u2571 \u2572 ",
176
+ " \u2502 \u25CF \u25CF \u2502 ",
177
+ " \u2502 \u2500\u2500 \u2502 ",
178
+ " \u2572 \u2502\u2502\u2502 \u2571 ",
179
+ " \u2572\u2550\u2567\u2567\u2550\u2571 ",
180
+ " \u2571\u2571\u2571\u2571 \u2572\u2572\u2572\u2572 ",
181
+ " \u2571\u2571\u2571\u2571 \u2572\u2572\u2572\u2572 "
87
182
  ],
88
183
  [
89
- " \u2571\u2572 \u2571\u2572 ",
90
- " \u2571 \u2572\u2500\u2500\u2571 \u2572 ",
91
- " \u2502 \u25C9 \u25C9 \u2502 ",
92
- " \u2502 \u2571\u2572 \u2502 ",
93
- " \u2572 \u2502\u2502\u2502 \u2571 ",
94
- " \u2572\u2550\u2567\u2567\u2550\u2571 ",
95
- " \u2571\u2571\u2572\u2572 ",
96
- " \u2571\u2571 \u2572\u2572 "
184
+ " \u2571\u2572 \u2571\u2572 ",
185
+ " \u2571 \u2572\u2500\u2500\u2571 \u2572 ",
186
+ " \u2502 \u25C9 \u25C9 \u2502 ",
187
+ " \u2502 \u2571\u2572 \u2502 ",
188
+ " \u2572 \u2502\u2502\u2502 \u2571 ",
189
+ " \u2572\u2550\u2567\u2567\u2550\u2571 ",
190
+ " \u2571\u2571\u2572\u2572 ",
191
+ " \u2571\u2571 \u2572\u2572 "
97
192
  ],
98
193
  [
99
- " \u2571\u2572 \u2571\u2572 ",
100
- " \u2571 \u2572\u2571 \u2572 ",
101
- " \u2502 \u25C9 \u25C9 \u2502 ",
102
- " \u2502 \u2572\u2571 \u2502 ",
103
- " \u2572 \u2502\u2502\u2502 \u2571 ",
104
- " \u2572\u2567\u2567\u2567\u2571 ",
105
- " \u2571\u2571\u2571 \u2572\u2572\u2572 ",
106
- " \u2571\u2571\u2571 \u2572\u2572\u2572 "
194
+ " \u2571\u2572 \u2571\u2572 ",
195
+ " \u2571 \u2572\u2571 \u2572 ",
196
+ " \u2502 \u25C9 \u25C9 \u2502 ",
197
+ " \u2502 \u2572\u2571 \u2502 ",
198
+ " \u2572 \u2502\u2502\u2502 \u2571 ",
199
+ " \u2572\u2567\u2567\u2567\u2571 ",
200
+ " \u2571\u2571\u2571 \u2572\u2572\u2572 ",
201
+ " \u2571\u2571\u2571 \u2572\u2572\u2572 "
107
202
  ]
108
203
  ];
109
204
  var LOBSTER_BIG = `
@@ -118,24 +213,39 @@ var LOBSTER_BIG = `
118
213
  \u2571\u2571\u2571 \u2502\u2588\u2502 \u2572\u2572\u2572
119
214
  \u2571\u2571 \u2571\u2588\u2588\u2588\u2572 \u2572\u2572
120
215
  `;
216
+ var LOBSTER_COLORS = [
217
+ chalk.hex(SOL_GREEN),
218
+ chalk.hex("#14F195"),
219
+ chalk.hex(NANO_CYAN),
220
+ chalk.hex("#00C9A7"),
221
+ chalk.hex("#14F195"),
222
+ chalk.hex(SOL_GREEN)
223
+ ];
121
224
  function animateLobster(durationMs = 2400) {
122
225
  return new Promise((resolve) => {
123
226
  const frameCount = LOBSTER_FRAMES.length;
124
- const frameH = LOBSTER_FRAMES[0].length + 1;
227
+ const frameH = LOBSTER_FRAMES[0].length + 2;
125
228
  let frame = 0;
126
229
  process.stdout.write("\n".repeat(frameH));
127
230
  const interval = setInterval(() => {
128
- process.stdout.write(`\x1B[${frameH}A`);
231
+ process.stdout.write(cursorUp(frameH));
129
232
  const f = LOBSTER_FRAMES[frame % frameCount];
130
- const color = frame % 2 === 0 ? chalk.green : chalk.hex("#14F195");
233
+ const color = LOBSTER_COLORS[frame % LOBSTER_COLORS.length];
131
234
  for (const line of f) {
132
- process.stdout.write(`\x1B[2K ${color(line)}
235
+ process.stdout.write(`${CLEAR_LINE} ${color(line)}
133
236
  `);
134
237
  }
135
- process.stdout.write(`\x1B[2K ${chalk.cyan(" \u{1F99E} NanoSolana")}
136
- `);
238
+ const sparkles = frame % 3 === 0 ? "\u2726" : frame % 3 === 1 ? "\u2727" : "\u22C6";
239
+ process.stdout.write(
240
+ `${CLEAR_LINE} ${chalk.hex(SOL_GREEN)(sparkles)} ${gradientText(" NanoSolana", SOLANA_GRADIENT)} ${chalk.hex(SOL_GREEN)(sparkles)}
241
+ `
242
+ );
243
+ process.stdout.write(
244
+ `${CLEAR_LINE} ${chalk.gray(" v1.0.1 \xB7 Solana Agent Framework")}
245
+ `
246
+ );
137
247
  frame++;
138
- }, 200);
248
+ }, 180);
139
249
  setTimeout(() => {
140
250
  clearInterval(interval);
141
251
  resolve();
@@ -143,25 +253,26 @@ function animateLobster(durationMs = 2400) {
143
253
  });
144
254
  }
145
255
  var DVD_LOGO = [
146
- "\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557",
147
- "\u2551 \u{1F99E} NanoSolana \u{1F99E} \u2551",
148
- "\u2551 \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 \u2551",
149
- "\u2551 Solana Trading Agent \u2551",
150
- "\u2551 nanosolana.com \u2551",
151
- "\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D"
256
+ "\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557",
257
+ "\u2551 \u{1F99E} NanoSolana \u{1F99E} \u2551",
258
+ "\u2551 \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 \u2551",
259
+ "\u2551 Autonomous Solana Agent \u2551",
260
+ "\u2551 OODA \xB7 ClawVault \xB7 TamaGOchi \u2551",
261
+ "\u2551 nanosolana.com \u2551",
262
+ "\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D"
152
263
  ];
153
264
  var DVD_COLORS = [
154
- chalk.hex("#14F195"),
155
- chalk.hex("#9945FF"),
156
- chalk.cyan,
157
- chalk.magenta,
158
- chalk.yellow,
159
- chalk.green,
160
- chalk.blue,
161
- chalk.red
265
+ chalk.hex(SOL_GREEN),
266
+ chalk.hex(SOL_PURPLE),
267
+ chalk.hex(NANO_CYAN),
268
+ chalk.hex(NANO_GOLD),
269
+ chalk.hex(NANO_BLUE),
270
+ chalk.hex("#FF6B6B"),
271
+ chalk.hex("#C084FC"),
272
+ chalk.hex("#34D399")
162
273
  ];
163
274
  function startDvdScreensaver() {
164
- const logoWidth = 27;
275
+ const logoWidth = 33;
165
276
  const logoHeight = DVD_LOGO.length;
166
277
  let cols = process.stdout.columns || 80;
167
278
  let rows = process.stdout.rows || 24;
@@ -171,87 +282,154 @@ function startDvdScreensaver() {
171
282
  let dy = 1;
172
283
  let colorIdx = 0;
173
284
  let hits = 0;
174
- process.stdout.write("\x1B[?25l\x1B[2J");
285
+ let cornerHits = 0;
286
+ process.stdout.write(`${HIDE_CURSOR}${CLEAR_SCREEN}`);
175
287
  const interval = setInterval(() => {
176
288
  cols = process.stdout.columns || 80;
177
289
  rows = process.stdout.rows || 24;
178
290
  for (let i = 0; i < logoHeight; i++) {
179
- process.stdout.write(`\x1B[${y + i + 1};1H\x1B[2K`);
291
+ process.stdout.write(clearLineAt(y + i + 1));
180
292
  }
181
293
  x += dx;
182
294
  y += dy;
295
+ let bounced = false;
183
296
  if (x <= 0 || x + logoWidth >= cols) {
184
297
  dx *= -1;
185
- colorIdx = (colorIdx + 1) % DVD_COLORS.length;
186
- hits++;
298
+ bounced = true;
187
299
  }
188
300
  if (y <= 0 || y + logoHeight >= rows - 1) {
189
301
  dy *= -1;
302
+ bounced = true;
303
+ }
304
+ if (bounced) {
190
305
  colorIdx = (colorIdx + 1) % DVD_COLORS.length;
191
306
  hits++;
307
+ if ((x <= 1 || x + logoWidth >= cols - 1) && (y <= 1 || y + logoHeight >= rows - 2)) {
308
+ cornerHits++;
309
+ }
192
310
  }
193
311
  x = Math.max(0, Math.min(x, cols - logoWidth));
194
312
  y = Math.max(0, Math.min(y, rows - logoHeight - 1));
195
313
  const color = DVD_COLORS[colorIdx];
196
314
  for (let i = 0; i < logoHeight; i++) {
197
- process.stdout.write(`\x1B[${y + i + 1};${x + 1}H`);
315
+ process.stdout.write(moveTo(y + i + 1, x + 1));
198
316
  process.stdout.write(color(DVD_LOGO[i]));
199
317
  }
200
- process.stdout.write(`\x1B[${rows};1H`);
318
+ process.stdout.write(moveTo(rows, 1));
319
+ const cornerText = cornerHits > 0 ? ` \u2502 \u{1F3AF} Corner: ${cornerHits}` : "";
201
320
  process.stdout.write(
202
- chalk.bgHex("#0a0a1a").hex("#14F195")(
203
- ` \u{1F99E} NanoSolana DVD | Bounces: ${hits} | ${(/* @__PURE__ */ new Date()).toLocaleTimeString()} | Ctrl+C to exit `.padEnd(
204
- cols
205
- )
321
+ chalk.bgHex("#0a0a1a").hex(SOL_GREEN)(
322
+ ` \u{1F99E} NanoSolana DVD \u2502 Bounces: ${hits}${cornerText} \u2502 ${(/* @__PURE__ */ new Date()).toLocaleTimeString()} \u2502 Ctrl+C to exit `.padEnd(cols)
206
323
  )
207
324
  );
208
- }, 60);
325
+ }, 50);
209
326
  const stop = () => {
210
327
  clearInterval(interval);
211
- process.stdout.write("\x1B[?25h\x1B[2J\x1B[H");
328
+ process.stdout.write(`${SHOW_CURSOR}${CLEAR_SCREEN}${HOME}`);
212
329
  };
213
330
  return { stop };
214
331
  }
332
+ function matrixRain(durationMs = 1500) {
333
+ return new Promise((resolve) => {
334
+ const cols = process.stdout.columns || 80;
335
+ const rows = process.stdout.rows || 24;
336
+ const chars = "\u2588\u2593\u2592\u2591\u256C\u256B\u256A\u253C\u2524\u251C\u2534\u252C\u2502\u2500\u25C9\u25CE\u25CB\u25CF\u25C6\u25C7\u2726\u2727\u22C6\u2605\u2606".split("");
337
+ const solChars = "SOLANANANOCLAWVAULTOODAx402".split("");
338
+ const drops = Array(cols).fill(0).map(() => Math.floor(Math.random() * -rows));
339
+ process.stdout.write(`${HIDE_CURSOR}${CLEAR_SCREEN}`);
340
+ const interval = setInterval(() => {
341
+ for (let c = 0; c < cols; c += 2) {
342
+ const y = drops[c];
343
+ if (y >= 0 && y < rows) {
344
+ const ch = Math.random() > 0.3 ? chars[Math.floor(Math.random() * chars.length)] : solChars[Math.floor(Math.random() * solChars.length)];
345
+ process.stdout.write(moveTo(y + 1, c + 1));
346
+ process.stdout.write(chalk.hex(SOL_GREEN).bold(ch));
347
+ if (y > 0 && y - 1 < rows) {
348
+ process.stdout.write(moveTo(y, c + 1));
349
+ process.stdout.write(chalk.hex(DIM_GREEN)(chars[Math.floor(Math.random() * chars.length)]));
350
+ }
351
+ if (y > 2 && y - 3 < rows) {
352
+ process.stdout.write(moveTo(y - 2, c + 1));
353
+ process.stdout.write(chalk.hex("#033d1a")(" "));
354
+ }
355
+ }
356
+ drops[c]++;
357
+ if (drops[c] > rows + 10) {
358
+ drops[c] = Math.floor(Math.random() * -5);
359
+ }
360
+ }
361
+ }, 35);
362
+ setTimeout(() => {
363
+ clearInterval(interval);
364
+ process.stdout.write(`${SHOW_CURSOR}${CLEAR_SCREEN}${HOME}`);
365
+ resolve();
366
+ }, durationMs);
367
+ });
368
+ }
215
369
  var STARTUP_STEPS = [
216
- { label: "Generating Ed25519 keypair...", spinner: "helix", durationMs: 400 },
217
- { label: "Deriving Solana wallet address...", spinner: "dna", durationMs: 300 },
218
- { label: "Encrypting private key (AES-256-GCM)...", spinner: "cascade", durationMs: 500 },
219
- { label: "Requesting devnet airdrop...", spinner: "orbit", durationMs: 700 },
220
- { label: "Minting Birth Certificate NFT (Metaplex)...", spinner: "scan", durationMs: 600 },
221
- { label: "Initializing ClawVault memory engine...", spinner: "rain", durationMs: 400 },
222
- { label: "Hatching TamaGOchi pet \u{1F95A}...", spinner: "breathe", durationMs: 500 },
223
- { label: "Calibrating RSI + EMA + ATR strategy...", spinner: "columns", durationMs: 400 },
224
- { label: "Starting OODA trading loop...", spinner: "snake", durationMs: 300 },
225
- { label: "Connecting gateway (HMAC-SHA256)...", spinner: "braille", durationMs: 400 }
370
+ { label: "Generating Ed25519 keypair", spinner: "helix", durationMs: 400, icon: "\u{1F510}" },
371
+ { label: "Deriving Solana wallet address", spinner: "dna", durationMs: 300, icon: "\u{1F45B}" },
372
+ { label: "Encrypting private key (AES-256-GCM)", spinner: "cascade", durationMs: 500, icon: "\u{1F512}" },
373
+ { label: "Requesting devnet airdrop", spinner: "orbit", durationMs: 700, icon: "\u{1F4B0}" },
374
+ { label: "Minting Birth Certificate (Metaplex)", spinner: "scan", durationMs: 600, icon: "\u{1F4DC}" },
375
+ { label: "Initializing ClawVault memory engine", spinner: "rain", durationMs: 400, icon: "\u{1F9E0}" },
376
+ { label: "Hatching TamaGOchi pet", spinner: "breathe", durationMs: 500, icon: "\u{1F95A}" },
377
+ { label: "Calibrating RSI + EMA + ATR strategy", spinner: "columns", durationMs: 400, icon: "\u{1F4C8}" },
378
+ { label: "Bootstrapping OODA trading loop", spinner: "snake", durationMs: 300, icon: "\u{1F504}" },
379
+ { label: "Initializing payment system (PumpAgent)", spinner: "sparkle", durationMs: 350, icon: "\u{1F4B3}" },
380
+ { label: "Connecting gateway (HMAC-SHA256)", spinner: "braille", durationMs: 400, icon: "\u{1F310}" }
226
381
  ];
227
382
  async function playStartupAnimation() {
228
- for (const step of STARTUP_STEPS) {
229
- await runWithSpinner(step.label, () => sleep(step.durationMs), step.spinner);
383
+ const total = STARTUP_STEPS.length;
384
+ for (let idx = 0; idx < total; idx++) {
385
+ const step = STARTUP_STEPS[idx];
386
+ const { frames, interval } = spinners[step.spinner];
387
+ let i = 0;
388
+ const percent = (idx + 1) / total;
389
+ const timer = setInterval(() => {
390
+ const spin = chalk.hex(NANO_CYAN)(frames[i++ % frames.length]);
391
+ const bar = progressBar(percent);
392
+ process.stdout.write(
393
+ `${CLEAR_LINE} ${spin} ${chalk.white(step.icon)} ${chalk.white(step.label)} ${bar}`
394
+ );
395
+ }, interval);
396
+ await sleep(step.durationMs);
397
+ clearInterval(timer);
398
+ process.stdout.write(
399
+ `${CLEAR_LINE} ${chalk.hex(SOL_GREEN)("\u2713")} ${step.icon} ${chalk.white(step.label)} ${progressBar(percent)}
400
+ `
401
+ );
230
402
  }
231
403
  }
232
404
  async function lobsterWalk(message) {
233
405
  const cols = process.stdout.columns || 80;
234
- const walkLen = Math.min(cols - 20, 35);
406
+ const walkLen = Math.min(cols - 30, 30);
235
407
  const { frames, interval } = spinners.braille;
236
408
  let fi = 0;
237
409
  for (let i = 0; i < walkLen; i++) {
238
410
  const pad = " ".repeat(i);
239
- const dots = chalk.hex("#14F195")("\xB7".repeat(Math.min(i, 6)));
240
- const spin = chalk.cyan(frames[fi++ % frames.length]);
241
- process.stdout.write(`\r\x1B[2K ${pad}${dots} ${spin} \u{1F99E}`);
411
+ const trail = gradientText("\xB7".repeat(Math.min(i, 8)), GRADIENT_COLORS);
412
+ const spin = chalk.hex(NANO_CYAN)(frames[fi++ % frames.length]);
413
+ process.stdout.write(`${CLEAR_LINE} ${pad}${trail} ${spin} \u{1F99E}`);
242
414
  await sleep(interval);
243
415
  }
244
- process.stdout.write(`\r\x1B[2K`);
245
- console.log(chalk.hex("#14F195")(` \u{1F99E} ${message}`));
416
+ process.stdout.write(CLEAR_LINE);
417
+ console.log(gradientText(` \u{1F99E} ${message}`, SOLANA_GRADIENT));
246
418
  }
247
419
  function printLobster() {
248
420
  const lines = LOBSTER_BIG.split("\n");
249
421
  for (const line of lines) {
250
- console.log(chalk.green(` ${line}`));
422
+ console.log(chalk.hex(SOL_GREEN)(` ${line}`));
251
423
  }
252
424
  }
253
- function sleep(ms) {
254
- return new Promise((resolve) => setTimeout(resolve, ms));
425
+ function printInitHeader() {
426
+ console.log();
427
+ console.log(gradientText(" \u2699 First Run Configuration", SOLANA_GRADIENT));
428
+ console.log(chalk.gray(" Let's set up your API keys and agent configuration\n"));
429
+ }
430
+ function printSectionHeader(title) {
431
+ console.log(chalk.hex(NANO_CYAN)(` \u2500\u2500 ${title} ${"\u2500".repeat(Math.max(0, 50 - title.length))}
432
+ `));
255
433
  }
256
434
 
257
435
  // src/onchain/helius-client.ts
@@ -1036,8 +1214,8 @@ function printBanner() {
1036
1214
  \u2588\u2588\u2551 \u255A\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u255A\u2588\u2588\u2588\u2588\u2551\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u255A\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551
1037
1215
  \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u2550\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D
1038
1216
  `));
1039
- console.log(chalk2.white(" \u{1F439} NanoSolana TamaGObot"));
1040
- console.log(chalk2.gray(" A GoBot on Solana \xB7 Physical Companion: TamaGOchi \xB7 By NanoSolana Labs\n"));
1217
+ console.log(chalk2.white(" \u{1F99E} NanoSolana TamaGObot"));
1218
+ console.log(chalk2.gray(" Autonomous Financial Intelligence on Solana \xB7 By NanoSolana Labs\n"));
1041
1219
  }
1042
1220
  async function promptSecret(question) {
1043
1221
  const rl = createInterface({ input: process.stdin, output: process.stdout });
@@ -1069,7 +1247,7 @@ function formatBytes(bytes) {
1069
1247
  return `${value.toFixed(1)} ${units[unitIndex]}`;
1070
1248
  }
1071
1249
  var program = new Command();
1072
- program.name("nanosolana").description("\u{1F99E} NanoSolana \u2014 Autonomous Solana trading intelligence with a virtual pet soul").version("1.0.0");
1250
+ program.name("nanosolana").description("\u{1F99E} NanoSolana \u2014 Autonomous Solana trading intelligence with a virtual pet soul").version("1.0.2");
1073
1251
  program.command("init").description("Initialize Nano Solana and configure API keys").action(async () => {
1074
1252
  printBanner();
1075
1253
  console.log(chalk2.white.bold(" \u{1F527} Initializing Nano Solana...\n"));
@@ -1528,17 +1706,18 @@ program.command("docs").description("Inspect integrated docs + extension knowled
1528
1706
  }
1529
1707
  });
1530
1708
  program.command("go").description("One-shot: init + birth + wallet + run \u2014 everything in one command").option("-n, --name <name>", "Agent name", "NanoSolana").option("--pet-name <petName>", "TamaGOchi pet name").option("--skip-init", "Skip API key prompts if already configured").action(async (opts) => {
1531
- printBanner();
1532
- await animateLobster(1800);
1709
+ await matrixRain(1200);
1710
+ await printSplashBanner();
1711
+ await animateLobster(2e3);
1533
1712
  console.log();
1534
1713
  try {
1535
- await lobsterWalk("Phase 1 \u2014 Initialization");
1714
+ await phaseTransition("init", "Phase 1 \u2014 Initialization");
1536
1715
  ensureNanoHome();
1537
1716
  const secrets = loadSecrets();
1538
1717
  const needsInit = !opts.skipInit && (!secrets.HELIUS_RPC_URL || !secrets.AI_API_KEY);
1539
1718
  if (needsInit) {
1540
- console.log(chalk2.yellow("\n First run detected \u2014 let's configure your API keys.\n"));
1541
- console.log(chalk2.cyan(" \u2500\u2500 Required Keys \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n"));
1719
+ printInitHeader();
1720
+ printSectionHeader("Required Keys");
1542
1721
  if (!secrets.AI_API_KEY) {
1543
1722
  secrets.AI_API_KEY = await promptSecret("OpenRouter API Key (sk-or-v1-...)");
1544
1723
  }