solana-terminator-skill 4.2.9 → 4.3.7

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/install.js CHANGED
@@ -6,7 +6,7 @@
6
6
  * Automates the setup of the Solana skill for the Conway Automaton.
7
7
  */
8
8
 
9
- import { execSync } from 'child_process';
9
+ import { execSync, spawnSync } from 'child_process';
10
10
  import fs from 'fs';
11
11
  import path from 'path';
12
12
  import { fileURLToPath } from 'url';
@@ -24,7 +24,7 @@ const ASCII_ART = `
24
24
  ██ ██████ ████████ ████ ████ ██ ████ ██ ███████ ██ ██ ██ ██████
25
25
  ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
26
26
  ██ ████████ ██ ██ ██ ██ ██ ██ ████ ██ ██ ██ ██████ ██ ██
27
- v4.2.7 - Autonomous Engine
27
+ v4.3.7 - Autonomous Engine
28
28
  `;
29
29
 
30
30
  const SKILL_NAME = 'solana-terminator';
@@ -35,13 +35,37 @@ const TARGET_DIR = path.join(os.homedir(), '.automaton', 'skills', SKILL_NAME);
35
35
  const args = process.argv.slice(2);
36
36
 
37
37
  if (args.includes('radar')) {
38
- import('./radar.js');
38
+ launchRadar(true);
39
39
  } else if (args.includes('install')) {
40
40
  runInstaller();
41
41
  } else {
42
42
  showMainMenu();
43
43
  }
44
44
 
45
+ // ─── Logic ─────────────────────────────────────────────────────────────
46
+
47
+ function launchRadar(isDirect = false) {
48
+ try {
49
+ const radarPath = path.join(__dirname, 'radar.js');
50
+
51
+ // Spawn independent process with inherited control
52
+ spawnSync('node', [radarPath], {
53
+ stdio: 'inherit',
54
+ shell: true
55
+ });
56
+
57
+ // After child process exits, we return here
58
+ if (!isDirect) {
59
+ showMainMenu();
60
+ } else {
61
+ process.exit(0);
62
+ }
63
+ } catch (e) {
64
+ if (!isDirect) showMainMenu();
65
+ else process.exit(1);
66
+ }
67
+ }
68
+
45
69
  // ─── Menu System ────────────────────────────────────────────────────────────
46
70
 
47
71
  function showMainMenu() {
@@ -63,7 +87,7 @@ function showMainMenu() {
63
87
  rl.close();
64
88
  switch (answer.toLowerCase()) {
65
89
  case '1': runInstaller(); break;
66
- case '2': import('./radar.js'); break;
90
+ case '2': launchRadar(); break;
67
91
  case '3': showIdentity(); break;
68
92
  case '4': showDocs(); break;
69
93
  case 'x': process.exit(0);
@@ -89,8 +113,9 @@ function showIdentity() {
89
113
  import('./solana-autonomy.js').then(async ({ SolanaAutonomy }) => {
90
114
  const solana = new SolanaAutonomy();
91
115
  const status = await solana.getStatus();
92
- console.log(`\n✅ AGENT IDENTITY FOUND`);
116
+ console.log(`\n✅ AGENT SOLANA IDENTITY FOUND`);
93
117
  console.log(`--------------------------------------------------`);
118
+ console.log(`NETWORK : Solana Mainnet-Beta`);
94
119
  console.log(`ADDRESS : ${status.address}`);
95
120
  console.log(`SOL : ${status.sol.toFixed(4)}`);
96
121
  console.log(`USDC : $${status.usdc.toFixed(2)}`);
@@ -115,11 +140,11 @@ function pauseAndReturn() {
115
140
  // ─── Installer Logic ────────────────────────────────────────────────────────
116
141
 
117
142
  async function runInstaller() {
143
+ process.stdout.write('\x1Bc');
118
144
  console.log(ASCII_ART);
119
145
  console.log(`🤖 Solana Terminator Skill — Initializing...\n`);
120
146
 
121
147
  try {
122
- // 1. Create target directory
123
148
  if (!fs.existsSync(TARGET_DIR)) {
124
149
  console.log(`[1/3] Creating directory: ${TARGET_DIR}`);
125
150
  fs.mkdirSync(TARGET_DIR, { recursive: true });
@@ -127,7 +152,6 @@ async function runInstaller() {
127
152
  console.log(`[1/3] Directory already exists: ${TARGET_DIR}`);
128
153
  }
129
154
 
130
- // 2. Copy files
131
155
  console.log(`[2/3] Copying skill files...`);
132
156
  const filesToCopy = ['solana-autonomy.js', 'SKILL.md', 'package.json', 'radar.js'];
133
157
 
@@ -142,12 +166,10 @@ async function runInstaller() {
142
166
  }
143
167
  });
144
168
 
145
- // 3. Install dependencies
146
169
  console.log(`[3/3] Installing dependencies in ${TARGET_DIR}...`);
147
170
  process.chdir(TARGET_DIR);
148
171
  execSync('npm install --production --omit=dev', { stdio: 'inherit' });
149
172
 
150
- // 4. Show/Generate Wallet Address
151
173
  console.log(`\n🔍 Initializing Agent Identity...`);
152
174
  try {
153
175
  const checkScript = `
package/package.json CHANGED
@@ -1,12 +1,11 @@
1
1
  {
2
2
  "name": "solana-terminator-skill",
3
- "version": "4.2.9",
4
- "description": "Full Solana toolkit for AI agents. Install via npx solana-terminator-skill.",
3
+ "version": "4.3.7",
4
+ "description": "Full Solana toolkit for AI agents. npx solana-terminator-skill.",
5
5
  "main": "solana-autonomy.js",
6
6
  "type": "module",
7
7
  "bin": {
8
- "solana-terminator-skill": "install.js",
9
- "radar": "radar.js"
8
+ "solana-terminator-skill": "install.js"
10
9
  },
11
10
  "files": [
12
11
  "solana-autonomy.js",
@@ -23,9 +22,11 @@
23
22
  "@solana/web3.js": "^1.87.6",
24
23
  "@solana/spl-token": "^0.3.9",
25
24
  "axios": "^1.6.2",
26
- "dotenv": "^16.3.1",
27
25
  "chalk": "^5.3.0",
28
- "ws": "^8.14.2",
26
+ "dotenv": "^16.3.1",
27
+ "ws": "^8.14.2"
28
+ },
29
+ "optionalDependencies": {
29
30
  "@raydium-io/raydium-sdk-v2": "0.2.32-alpha"
30
31
  },
31
32
  "keywords": [
package/radar.js CHANGED
@@ -9,6 +9,9 @@
9
9
  import chalk from 'chalk';
10
10
  import WebSocket from 'ws';
11
11
  import { SolanaAutonomy } from './solana-autonomy.js';
12
+ import fs from 'fs';
13
+ import path from 'path';
14
+ import os from 'os';
12
15
 
13
16
  const solana = new SolanaAutonomy();
14
17
  const green = chalk.green;
@@ -17,6 +20,21 @@ const alert = chalk.yellow;
17
20
  const critical = chalk.red;
18
21
  const dim = chalk.gray;
19
22
 
23
+ const MISSION_LOG_PATH = path.join(os.homedir(), '.automaton', 'mission.log');
24
+
25
+ // ─── State ──────────────────────────────────────────────────────────────────
26
+
27
+ let status = {
28
+ sol: 0,
29
+ usdc: 0,
30
+ tier: 'NOMINAL',
31
+ logs: [],
32
+ mints: []
33
+ };
34
+
35
+ let intervals = [];
36
+ let wsClient = null;
37
+
20
38
  // ─── UI Helpers ─────────────────────────────────────────────────────────────
21
39
 
22
40
  function clear() {
@@ -31,16 +49,6 @@ function header(text) {
31
49
  console.log(chalk.bgBlack.white.bold(` ${text} `));
32
50
  }
33
51
 
34
- // ─── State ──────────────────────────────────────────────────────────────────
35
-
36
- let status = {
37
- sol: 0,
38
- usdc: 0,
39
- tier: 'NOMINAL',
40
- logs: [],
41
- mints: []
42
- };
43
-
44
52
  // ─── Rendering ──────────────────────────────────────────────────────────────
45
53
 
46
54
  async function render() {
@@ -50,9 +58,9 @@ async function render() {
50
58
  ██ ██ ██ ██ ██ ██ ████ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
51
59
  █████ ██ ██ ██ ███████ ██ ██ ██ ███████ ██████ ███████ ██ ██ ███████ ██████
52
60
  ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
53
- ██████ ██████ ███████ ██ ██ ██ ████ ██ ██ ██ ██ ██ ██ ██████ ██ ██ ██ ██
54
- v4.2.7 RADAR
55
- `));
61
+ ██████ ██████ ███████ ██ ██ ██ ████ ██ ██ ██ ██ ██ ██ ██████ ██ ██ ██████
62
+ v4.3.7 RADAR
63
+ `));
56
64
 
57
65
  line();
58
66
  header('VITAL SIGNS');
@@ -60,26 +68,37 @@ async function render() {
60
68
  console.log(` SOL: ${neon(status.sol.toFixed(4))} | USDC: ${neon('$' + status.usdc.toFixed(2))} | TIER: ${tierColor.bold(status.tier)}`);
61
69
 
62
70
  line();
63
- header('PREDATOR RADAR (Pump.fun Live)');
64
- const recentMints = status.mints.slice(-8).reverse();
71
+ header('MISSION CONTROL (The Brain Logs)');
72
+ const missionLogs = status.logs.slice(-6).reverse();
73
+ if (missionLogs.length === 0) {
74
+ console.log(dim(' Waiting for the Brain to issue commands...'));
75
+ } else {
76
+ missionLogs.forEach(l => {
77
+ console.log(` ${green('⦿')} ${l}`);
78
+ });
79
+ }
80
+
81
+ line();
82
+ header('P.R.E.D.A.T.O.R. RADAR (Market Live)');
83
+ const recentMints = status.mints.slice(-4).reverse();
65
84
  if (recentMints.length === 0) {
66
- console.log(dim(' Waiting for new transmissions...'));
85
+ console.log(dim(' Awaiting neural transmissions from PumpPortal...'));
67
86
  } else {
68
87
  recentMints.forEach(m => {
69
88
  const secBadge = m.safe ? green('🛡️ SAFE') : critical('⚠️ RISKY');
70
- console.log(` [${dim(m.time)}] ${neon(m.symbol.padEnd(8))} | VOL: ${alert(m.vol)} | ${secBadge} | ${dim(m.mint.slice(0, 8) + '...')}`);
89
+ console.log(` [${dim(m.time)}] ${neon(m.symbol.padEnd(8))} | ${secBadge} | ${dim(m.mint.slice(0, 16))}`);
71
90
  });
72
91
  }
73
92
 
74
93
  line();
75
- header('DECISION LOG');
76
- const recentLogs = status.logs.slice(-5).reverse();
77
- recentLogs.forEach(l => {
78
- console.log(` ${dim('>')} ${l}`);
79
- });
94
+ header('AUTONOMIC MODULES STATUS');
95
+ console.log(` ${green('ONLINE')} : ${dim('Jupiter v6 Aggregator | Raydium V2 AMM/CLMM | Tensor NFTPredator')}`);
96
+ console.log(` ${green('ONLINE')} : ${dim('Meteora DLMM Liquidity | Birdeye Audit v2 | DexScreener AlphaScan')}`);
97
+ console.log(` ${green('ONLINE')} : ${dim('PumpPortal Live Sync | Solana Staking Module | Priority Fee Engine')}`);
80
98
 
81
99
  line();
82
- process.stdout.write(green(' COMMAND CENTER ACTIVE. REASONING IN PROGRESS... '));
100
+ console.log(dim(` Mission Log: ${MISSION_LOG_PATH}`));
101
+ console.log(green(' COMMAND CENTER ACTIVE. PRESS [q] TO EXIT.'));
83
102
  }
84
103
 
85
104
  // ─── Logic ──────────────────────────────────────────────────────────────────
@@ -91,57 +110,103 @@ async function updateVitals() {
91
110
  status.usdc = stats.usdc;
92
111
  status.tier = stats.solLow ? 'CRITICAL' : (stats.usdcLow ? 'WARNING' : 'NOMINAL');
93
112
  } catch (err) {
94
- status.logs.push(critical(`Vitals check failed: ${err.message}`));
113
+ // ignore
95
114
  }
96
115
  }
97
116
 
98
117
  function startWebSocket() {
99
- const ws = new WebSocket('wss://pumpportal.fun/api/data');
118
+ try {
119
+ wsClient = new WebSocket('wss://pumpportal.fun/api/data');
120
+ wsClient.on('open', () => {
121
+ wsClient.send(JSON.stringify({ method: 'subscribeNewToken' }));
122
+ });
123
+ wsClient.on('message', async (data) => {
124
+ const payload = JSON.parse(data);
125
+ if (payload.txType === 'create') {
126
+ const security = await solana.auditTokenSecurity(payload.mint);
127
+ status.mints.push({
128
+ time: new Date().toLocaleTimeString(),
129
+ symbol: payload.symbol,
130
+ mint: payload.mint,
131
+ vol: '$0',
132
+ safe: security.safe
133
+ });
134
+ }
135
+ });
136
+ } catch (e) {
137
+ // ignore
138
+ }
139
+ }
100
140
 
101
- ws.on('open', () => {
102
- ws.send(JSON.stringify({ method: 'subscribeNewToken' }));
103
- status.logs.push(green('Uplink established with PumpPortal WS.'));
104
- });
141
+ function tailMissionLog() {
142
+ if (fs.existsSync(MISSION_LOG_PATH)) {
143
+ // Read last few lines immediately
144
+ const content = fs.readFileSync(MISSION_LOG_PATH, 'utf8').split('\n').filter(Boolean);
145
+ status.logs = content.slice(-10);
146
+
147
+ // Watch for changes
148
+ fs.watchFile(MISSION_LOG_PATH, { interval: 1000 }, () => {
149
+ const updated = fs.readFileSync(MISSION_LOG_PATH, 'utf8').split('\n').filter(Boolean);
150
+ status.logs = updated.slice(-10);
151
+ render();
152
+ });
153
+ } else {
154
+ // Create empty log if it doesn't exist
155
+ fs.mkdirSync(path.dirname(MISSION_LOG_PATH), { recursive: true });
156
+ fs.writeFileSync(MISSION_LOG_PATH, '');
157
+ }
158
+ }
105
159
 
106
- ws.on('message', async (data) => {
107
- const payload = JSON.parse(data);
108
- if (payload.txType === 'create') {
109
- const security = await solana.auditTokenSecurity(payload.mint);
110
- status.mints.push({
111
- time: new Date().toLocaleTimeString(),
112
- symbol: payload.symbol,
113
- mint: payload.mint,
114
- vol: '$0', // New mint
115
- safe: security.safe
116
- });
117
-
118
- if (security.safe) {
119
- status.logs.push(neon(`Target detected: ${payload.symbol}. Volume spike expected. Security verified.`));
120
- }
160
+ // ─── Process Management ──────────────────────────────────────────────────────
161
+
162
+ function setupKeyboard() {
163
+ if (!process.stdin.isTTY) return;
164
+
165
+ process.stdin.setRawMode(true);
166
+ process.stdin.resume();
167
+ process.stdin.setEncoding('utf8');
168
+
169
+ process.stdin.on('data', (key) => {
170
+ // q, Ctrl+C, Ctrl+D
171
+ if (key === 'q' || key === '\u0003' || key === '\u0004') {
172
+ intervals.forEach(clearInterval);
173
+ if (wsClient) wsClient.close();
174
+ process.stdin.setRawMode(false);
175
+ process.stdin.pause();
176
+ process.exit(0);
121
177
  }
122
178
  });
123
179
 
124
- ws.on('error', (err) => {
125
- status.logs.push(critical(`WebSocket error: ${err.message}`));
126
- });
180
+ process.on('SIGTERM', () => process.exit(0));
127
181
  }
128
182
 
129
- // ─── Main Loop ──────────────────────────────────────────────────────────────
183
+ // ─── Entry Point ─────────────────────────────────────────────────────────────
184
+
185
+ async function main() {
186
+ setupKeyboard();
187
+ tailMissionLog();
188
+
189
+ // Initial welcome log
190
+ solana.logMission('Radar Station Established. Connecting to Neural Engine...');
191
+ solana.logMission('Module Scan: Jupiter Aggregator... [OK]');
192
+ solana.logMission('Module Scan: Raydium AMM V2... [OK]');
193
+ solana.logMission('Module Scan: Tensor NFT Engine... [OK]');
194
+
195
+ render();
130
196
 
131
- async function bootstrap() {
132
- status.logs.push('Initializing Solana Autonomy identity...');
133
197
  await updateVitals();
134
198
  startWebSocket();
135
199
 
136
- setInterval(async () => {
200
+ const interval = setInterval(async () => {
137
201
  await updateVitals();
138
202
  render();
139
- }, 2000); // 2s tick
203
+ }, 3000);
204
+ intervals.push(interval);
140
205
 
141
206
  render();
142
207
  }
143
208
 
144
- bootstrap().catch(err => {
209
+ main().catch(err => {
145
210
  console.error(critical(`FATAL ERROR: ${err.message}`));
146
211
  process.exit(1);
147
212
  });
@@ -71,6 +71,11 @@ export class SolanaAutonomy {
71
71
  'solana-wallet.json',
72
72
  );
73
73
  this.identity = this._loadIdentity();
74
+ this.missionLogPath = path.join(
75
+ process.env.HOME || '/root',
76
+ '.automaton',
77
+ 'mission.log',
78
+ );
74
79
  }
75
80
 
76
81
  // ─── Identity ─────────────────────────────────────────────────────────────
@@ -278,7 +283,22 @@ export class SolanaAutonomy {
278
283
 
279
284
  _logAction(message) {
280
285
  const timestamp = new Date().toISOString().split('T')[1].split('.')[0];
281
- console.log(`[DECISION][${timestamp}] ${message}`);
286
+ const logMessage = `[${timestamp}] ${message}`;
287
+ console.log(`[DECISION]${logMessage}`);
288
+
289
+ // Append to shared mission log for Radar tailing
290
+ try {
291
+ fs.appendFileSync(this.missionLogPath, logMessage + '\n');
292
+ } catch (e) {
293
+ // ignore
294
+ }
295
+ }
296
+
297
+ /**
298
+ * logMission — External hook for mission logs
299
+ */
300
+ logMission(message) {
301
+ this._logAction(message);
282
302
  }
283
303
 
284
304
  // ─── Jupiter Swaps ────────────────────────────────────────────────────────