scorpion-cli 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.
@@ -0,0 +1,134 @@
1
+ /**
2
+ * Shell Tools
3
+ * Execute PowerShell and CMD commands
4
+ */
5
+
6
+ import { exec } from 'child_process';
7
+ import { promisify } from 'util';
8
+
9
+ const execAsync = promisify(exec);
10
+
11
+ // Tool: run_command
12
+ export const runCommand = {
13
+ schema: {
14
+ type: 'function',
15
+ function: {
16
+ name: 'run_command',
17
+ description: 'Execute a shell command in PowerShell. Use this to run system commands, list files, check processes, etc.',
18
+ parameters: {
19
+ type: 'object',
20
+ required: ['command'],
21
+ properties: {
22
+ command: {
23
+ type: 'string',
24
+ description: 'The command to execute (e.g., "Get-Process", "dir", "systeminfo")'
25
+ },
26
+ timeout: {
27
+ type: 'integer',
28
+ description: 'Timeout in milliseconds (default: 30000)'
29
+ }
30
+ }
31
+ }
32
+ }
33
+ },
34
+ execute: async ({ command, timeout = 30000 }) => {
35
+ try {
36
+ const { stdout, stderr } = await execAsync(command, {
37
+ shell: 'powershell.exe',
38
+ timeout,
39
+ maxBuffer: 1024 * 1024 * 10, // 10MB buffer
40
+ windowsHide: true
41
+ });
42
+
43
+ return JSON.stringify({
44
+ success: true,
45
+ stdout: stdout.trim(),
46
+ stderr: stderr.trim() || undefined
47
+ });
48
+ } catch (error) {
49
+ return JSON.stringify({
50
+ success: false,
51
+ error: error.message,
52
+ stderr: error.stderr?.trim(),
53
+ code: error.code
54
+ });
55
+ }
56
+ }
57
+ };
58
+
59
+ // Tool: run_powershell_script
60
+ export const runPowershellScript = {
61
+ schema: {
62
+ type: 'function',
63
+ function: {
64
+ name: 'run_powershell_script',
65
+ description: 'Execute a multi-line PowerShell script. Use for complex operations that require multiple commands.',
66
+ parameters: {
67
+ type: 'object',
68
+ required: ['script'],
69
+ properties: {
70
+ script: {
71
+ type: 'string',
72
+ description: 'The PowerShell script to execute (can be multi-line)'
73
+ }
74
+ }
75
+ }
76
+ }
77
+ },
78
+ execute: async ({ script }) => {
79
+ try {
80
+ // Encode script to base64 to handle special characters
81
+ const encodedScript = Buffer.from(script, 'utf16le').toString('base64');
82
+
83
+ const { stdout, stderr } = await execAsync(
84
+ `powershell.exe -NoProfile -NonInteractive -EncodedCommand ${encodedScript}`,
85
+ {
86
+ timeout: 60000,
87
+ maxBuffer: 1024 * 1024 * 10,
88
+ windowsHide: true
89
+ }
90
+ );
91
+
92
+ return JSON.stringify({
93
+ success: true,
94
+ stdout: stdout.trim(),
95
+ stderr: stderr.trim() || undefined
96
+ });
97
+ } catch (error) {
98
+ return JSON.stringify({
99
+ success: false,
100
+ error: error.message,
101
+ stderr: error.stderr?.trim()
102
+ });
103
+ }
104
+ }
105
+ };
106
+
107
+ // Tool: get_environment_variable
108
+ export const getEnvVariable = {
109
+ schema: {
110
+ type: 'function',
111
+ function: {
112
+ name: 'get_environment_variable',
113
+ description: 'Get the value of an environment variable',
114
+ parameters: {
115
+ type: 'object',
116
+ required: ['name'],
117
+ properties: {
118
+ name: {
119
+ type: 'string',
120
+ description: 'Name of the environment variable (e.g., "PATH", "USERPROFILE")'
121
+ }
122
+ }
123
+ }
124
+ }
125
+ },
126
+ execute: async ({ name }) => {
127
+ const value = process.env[name];
128
+ return JSON.stringify({
129
+ name,
130
+ value: value || null,
131
+ exists: value !== undefined
132
+ });
133
+ }
134
+ };
@@ -0,0 +1,379 @@
1
+ /**
2
+ * System Tools
3
+ * System monitoring and analysis
4
+ */
5
+
6
+ import si from 'systeminformation';
7
+ import os from 'os';
8
+
9
+ // Tool: get_cpu_usage
10
+ export const getCpuUsage = {
11
+ schema: {
12
+ type: 'function',
13
+ function: {
14
+ name: 'get_cpu_usage',
15
+ description: 'Get current CPU usage and information',
16
+ parameters: {
17
+ type: 'object',
18
+ properties: {}
19
+ }
20
+ }
21
+ },
22
+ execute: async () => {
23
+ try {
24
+ const [cpu, load, speed] = await Promise.all([
25
+ si.cpu(),
26
+ si.currentLoad(),
27
+ si.cpuCurrentSpeed()
28
+ ]);
29
+
30
+ return JSON.stringify({
31
+ success: true,
32
+ model: `${cpu.manufacturer} ${cpu.brand}`,
33
+ cores: cpu.cores,
34
+ physicalCores: cpu.physicalCores,
35
+ speed: `${speed.avg.toFixed(2)} GHz`,
36
+ usage: {
37
+ total: `${load.currentLoad.toFixed(1)}%`,
38
+ user: `${load.currentLoadUser.toFixed(1)}%`,
39
+ system: `${load.currentLoadSystem.toFixed(1)}%`,
40
+ idle: `${load.currentLoadIdle.toFixed(1)}%`
41
+ },
42
+ perCore: load.cpus.map((c, i) => ({
43
+ core: i,
44
+ load: `${c.load.toFixed(1)}%`
45
+ }))
46
+ });
47
+ } catch (error) {
48
+ return JSON.stringify({ success: false, error: error.message });
49
+ }
50
+ }
51
+ };
52
+
53
+ // Tool: get_memory_usage
54
+ export const getMemoryUsage = {
55
+ schema: {
56
+ type: 'function',
57
+ function: {
58
+ name: 'get_memory_usage',
59
+ description: 'Get current memory (RAM) usage',
60
+ parameters: {
61
+ type: 'object',
62
+ properties: {}
63
+ }
64
+ }
65
+ },
66
+ execute: async () => {
67
+ try {
68
+ const mem = await si.mem();
69
+
70
+ return JSON.stringify({
71
+ success: true,
72
+ total: formatBytes(mem.total),
73
+ used: formatBytes(mem.used),
74
+ free: formatBytes(mem.free),
75
+ available: formatBytes(mem.available),
76
+ usagePercent: `${((mem.used / mem.total) * 100).toFixed(1)}%`,
77
+ swap: {
78
+ total: formatBytes(mem.swaptotal),
79
+ used: formatBytes(mem.swapused),
80
+ free: formatBytes(mem.swapfree)
81
+ }
82
+ });
83
+ } catch (error) {
84
+ return JSON.stringify({ success: false, error: error.message });
85
+ }
86
+ }
87
+ };
88
+
89
+ // Tool: get_disk_usage
90
+ export const getDiskUsage = {
91
+ schema: {
92
+ type: 'function',
93
+ function: {
94
+ name: 'get_disk_usage',
95
+ description: 'Get disk/storage usage for all drives',
96
+ parameters: {
97
+ type: 'object',
98
+ properties: {
99
+ drive: {
100
+ type: 'string',
101
+ description: 'Specific drive letter to check (e.g., "C:"). If not provided, shows all drives.'
102
+ }
103
+ }
104
+ }
105
+ }
106
+ },
107
+ execute: async ({ drive } = {}) => {
108
+ try {
109
+ const disks = await si.fsSize();
110
+
111
+ let filtered = disks;
112
+ if (drive) {
113
+ filtered = disks.filter(d =>
114
+ d.mount.toLowerCase().startsWith(drive.toLowerCase())
115
+ );
116
+ }
117
+
118
+ return JSON.stringify({
119
+ success: true,
120
+ drives: filtered.map(d => ({
121
+ mount: d.mount,
122
+ type: d.type,
123
+ total: formatBytes(d.size),
124
+ used: formatBytes(d.used),
125
+ free: formatBytes(d.available),
126
+ usagePercent: `${d.use.toFixed(1)}%`
127
+ }))
128
+ });
129
+ } catch (error) {
130
+ return JSON.stringify({ success: false, error: error.message });
131
+ }
132
+ }
133
+ };
134
+
135
+ // Tool: get_running_processes
136
+ export const getRunningProcesses = {
137
+ schema: {
138
+ type: 'function',
139
+ function: {
140
+ name: 'get_running_processes',
141
+ description: 'List running processes sorted by CPU or memory usage',
142
+ parameters: {
143
+ type: 'object',
144
+ properties: {
145
+ sort_by: {
146
+ type: 'string',
147
+ enum: ['cpu', 'memory'],
148
+ description: 'Sort by CPU or memory usage (default: cpu)'
149
+ },
150
+ limit: {
151
+ type: 'integer',
152
+ description: 'Number of processes to return (default: 10)'
153
+ }
154
+ }
155
+ }
156
+ }
157
+ },
158
+ execute: async ({ sort_by = 'cpu', limit = 10 }) => {
159
+ try {
160
+ const processes = await si.processes();
161
+
162
+ const sorted = processes.list
163
+ .sort((a, b) => {
164
+ if (sort_by === 'memory') {
165
+ return b.memRss - a.memRss;
166
+ }
167
+ return b.cpu - a.cpu;
168
+ })
169
+ .slice(0, limit);
170
+
171
+ return JSON.stringify({
172
+ success: true,
173
+ totalProcesses: processes.all,
174
+ running: processes.running,
175
+ blocked: processes.blocked,
176
+ topProcesses: sorted.map(p => ({
177
+ pid: p.pid,
178
+ name: p.name,
179
+ cpu: `${p.cpu.toFixed(1)}%`,
180
+ memory: formatBytes(p.memRss),
181
+ memoryPercent: `${p.mem.toFixed(1)}%`,
182
+ state: p.state
183
+ }))
184
+ });
185
+ } catch (error) {
186
+ return JSON.stringify({ success: false, error: error.message });
187
+ }
188
+ }
189
+ };
190
+
191
+ // Tool: get_system_info
192
+ export const getSystemInfo = {
193
+ schema: {
194
+ type: 'function',
195
+ function: {
196
+ name: 'get_system_info',
197
+ description: 'Get comprehensive system information (OS, hardware, uptime)',
198
+ parameters: {
199
+ type: 'object',
200
+ properties: {}
201
+ }
202
+ }
203
+ },
204
+ execute: async () => {
205
+ try {
206
+ const [osInfo, system, bios, time] = await Promise.all([
207
+ si.osInfo(),
208
+ si.system(),
209
+ si.bios(),
210
+ si.time()
211
+ ]);
212
+
213
+ return JSON.stringify({
214
+ success: true,
215
+ os: {
216
+ platform: osInfo.platform,
217
+ distro: osInfo.distro,
218
+ release: osInfo.release,
219
+ arch: osInfo.arch,
220
+ hostname: osInfo.hostname
221
+ },
222
+ system: {
223
+ manufacturer: system.manufacturer,
224
+ model: system.model,
225
+ version: system.version
226
+ },
227
+ bios: {
228
+ vendor: bios.vendor,
229
+ version: bios.version
230
+ },
231
+ uptime: formatUptime(time.uptime),
232
+ currentTime: new Date().toISOString(),
233
+ timezone: time.timezone
234
+ });
235
+ } catch (error) {
236
+ return JSON.stringify({ success: false, error: error.message });
237
+ }
238
+ }
239
+ };
240
+
241
+ // Tool: analyze_performance
242
+ export const analyzePerformance = {
243
+ schema: {
244
+ type: 'function',
245
+ function: {
246
+ name: 'analyze_performance',
247
+ description: 'Get a comprehensive performance snapshot including CPU, memory, disk, and top processes',
248
+ parameters: {
249
+ type: 'object',
250
+ properties: {}
251
+ }
252
+ }
253
+ },
254
+ execute: async () => {
255
+ try {
256
+ const [cpu, load, mem, disks, processes, osInfo, time] = await Promise.all([
257
+ si.cpu(),
258
+ si.currentLoad(),
259
+ si.mem(),
260
+ si.fsSize(),
261
+ si.processes(),
262
+ si.osInfo(),
263
+ si.time()
264
+ ]);
265
+
266
+ // Get top 5 processes by CPU
267
+ const topProcesses = processes.list
268
+ .sort((a, b) => b.cpu - a.cpu)
269
+ .slice(0, 5)
270
+ .map(p => ({
271
+ name: p.name,
272
+ cpu: `${p.cpu.toFixed(1)}%`,
273
+ memory: formatBytes(p.memRss)
274
+ }));
275
+
276
+ return JSON.stringify({
277
+ success: true,
278
+ timestamp: new Date().toISOString(),
279
+ system: {
280
+ hostname: osInfo.hostname,
281
+ os: `${osInfo.distro} ${osInfo.release}`,
282
+ uptime: formatUptime(time.uptime)
283
+ },
284
+ cpu: {
285
+ model: `${cpu.manufacturer} ${cpu.brand}`,
286
+ cores: cpu.cores,
287
+ usage: `${load.currentLoad.toFixed(1)}%`
288
+ },
289
+ memory: {
290
+ total: formatBytes(mem.total),
291
+ used: formatBytes(mem.used),
292
+ free: formatBytes(mem.available),
293
+ usagePercent: `${((mem.used / mem.total) * 100).toFixed(1)}%`
294
+ },
295
+ storage: disks.map(d => ({
296
+ drive: d.mount,
297
+ total: formatBytes(d.size),
298
+ used: formatBytes(d.used),
299
+ free: formatBytes(d.available),
300
+ usagePercent: `${d.use.toFixed(1)}%`
301
+ })),
302
+ topProcesses,
303
+ processCount: processes.all
304
+ });
305
+ } catch (error) {
306
+ return JSON.stringify({ success: false, error: error.message });
307
+ }
308
+ }
309
+ };
310
+
311
+ // Tool: get_network_info
312
+ export const getNetworkInfo = {
313
+ schema: {
314
+ type: 'function',
315
+ function: {
316
+ name: 'get_network_info',
317
+ description: 'Get network interfaces and connection information',
318
+ parameters: {
319
+ type: 'object',
320
+ properties: {}
321
+ }
322
+ }
323
+ },
324
+ execute: async () => {
325
+ try {
326
+ const [interfaces, stats, defaultGateway] = await Promise.all([
327
+ si.networkInterfaces(),
328
+ si.networkStats(),
329
+ si.networkGatewayDefault()
330
+ ]);
331
+
332
+ return JSON.stringify({
333
+ success: true,
334
+ defaultGateway,
335
+ interfaces: interfaces
336
+ .filter(i => i.ip4)
337
+ .map(i => ({
338
+ name: i.iface,
339
+ type: i.type,
340
+ ip4: i.ip4,
341
+ ip6: i.ip6,
342
+ mac: i.mac,
343
+ speed: i.speed ? `${i.speed} Mbps` : 'Unknown'
344
+ })),
345
+ stats: stats.map(s => ({
346
+ interface: s.iface,
347
+ rxBytes: formatBytes(s.rx_bytes),
348
+ txBytes: formatBytes(s.tx_bytes),
349
+ rxSpeed: formatBytes(s.rx_sec) + '/s',
350
+ txSpeed: formatBytes(s.tx_sec) + '/s'
351
+ }))
352
+ });
353
+ } catch (error) {
354
+ return JSON.stringify({ success: false, error: error.message });
355
+ }
356
+ }
357
+ };
358
+
359
+ // Helper functions
360
+ function formatBytes(bytes) {
361
+ if (!bytes || bytes === 0) return '0 B';
362
+ const k = 1024;
363
+ const sizes = ['B', 'KB', 'MB', 'GB', 'TB'];
364
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
365
+ return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
366
+ }
367
+
368
+ function formatUptime(seconds) {
369
+ const days = Math.floor(seconds / 86400);
370
+ const hours = Math.floor((seconds % 86400) / 3600);
371
+ const minutes = Math.floor((seconds % 3600) / 60);
372
+
373
+ const parts = [];
374
+ if (days > 0) parts.push(`${days}d`);
375
+ if (hours > 0) parts.push(`${hours}h`);
376
+ if (minutes > 0) parts.push(`${minutes}m`);
377
+
378
+ return parts.join(' ') || '< 1m';
379
+ }