vibex-sh 0.1.1 → 0.2.1
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/index.js +93 -15
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -3,17 +3,38 @@ import { io } from 'socket.io-client';
|
|
|
3
3
|
import { program, Command } from 'commander';
|
|
4
4
|
import { readFile, writeFile, mkdir } from 'fs/promises';
|
|
5
5
|
import { existsSync, readFileSync } from 'fs';
|
|
6
|
-
import { join } from 'path';
|
|
6
|
+
import { join, dirname } from 'path';
|
|
7
7
|
import { homedir } from 'os';
|
|
8
8
|
import { spawn } from 'child_process';
|
|
9
9
|
import http from 'http';
|
|
10
10
|
import https from 'https';
|
|
11
|
+
import { fileURLToPath } from 'url';
|
|
12
|
+
|
|
13
|
+
// Get version from package.json
|
|
14
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
15
|
+
const __dirname = dirname(__filename);
|
|
16
|
+
const packageJsonPath = join(__dirname, 'package.json');
|
|
17
|
+
let cliVersion = '0.0.0';
|
|
18
|
+
try {
|
|
19
|
+
const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf8'));
|
|
20
|
+
cliVersion = packageJson.version || '0.0.0';
|
|
21
|
+
} catch (error) {
|
|
22
|
+
// Fallback if package.json can't be read - try to read from parent directory
|
|
23
|
+
try {
|
|
24
|
+
const parentPackageJsonPath = join(__dirname, '..', 'package.json');
|
|
25
|
+
const packageJson = JSON.parse(readFileSync(parentPackageJsonPath, 'utf8'));
|
|
26
|
+
cliVersion = packageJson.version || '0.0.0';
|
|
27
|
+
} catch (e) {
|
|
28
|
+
// If both fail, use default
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
import crypto from 'crypto';
|
|
11
33
|
|
|
12
34
|
function generateSessionId() {
|
|
13
35
|
// Generate secure random session ID with 12 characters (as per security plan)
|
|
14
36
|
// Format: vibex-{12 random alphanumeric chars}
|
|
15
37
|
// Using crypto for better randomness
|
|
16
|
-
const crypto = require('crypto');
|
|
17
38
|
const chars = 'abcdefghijklmnopqrstuvwxyz0123456789';
|
|
18
39
|
let result = 'vibex-';
|
|
19
40
|
|
|
@@ -281,7 +302,7 @@ function printBanner(sessionId, webUrl, authCode = null) {
|
|
|
281
302
|
|
|
282
303
|
console.log('\n');
|
|
283
304
|
console.log(' ╔═══════════════════════════════════════╗');
|
|
284
|
-
console.log(' ║ 🔍 vibex.sh is watching...
|
|
305
|
+
console.log(' ║ 🔍 vibex.sh is watching... ║');
|
|
285
306
|
console.log(' ╚═══════════════════════════════════════╝');
|
|
286
307
|
console.log('\n');
|
|
287
308
|
console.log(` Session ID: ${sessionId}`);
|
|
@@ -293,12 +314,19 @@ function printBanner(sessionId, webUrl, authCode = null) {
|
|
|
293
314
|
}
|
|
294
315
|
|
|
295
316
|
async function main() {
|
|
296
|
-
// Handle
|
|
297
|
-
// Check process.argv directly - look for 'login' as a standalone argument
|
|
298
|
-
// This must happen FIRST, before any commander parsing
|
|
317
|
+
// Handle --version flag early (before commander parses)
|
|
299
318
|
const allArgs = process.argv;
|
|
300
319
|
const args = process.argv.slice(2);
|
|
301
320
|
|
|
321
|
+
// Check for --version or -V flag
|
|
322
|
+
if (allArgs.includes('--version') || allArgs.includes('-V') || args.includes('--version') || args.includes('-V')) {
|
|
323
|
+
console.log(cliVersion);
|
|
324
|
+
process.exit(0);
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
// Handle login command separately - check BEFORE commander parses
|
|
328
|
+
// Check process.argv directly - look for 'login' as a standalone argument
|
|
329
|
+
// This must happen FIRST, before any commander parsing
|
|
302
330
|
// Check if 'login' appears anywhere in process.argv (works with npx too)
|
|
303
331
|
const hasLogin = allArgs.includes('login') || args.includes('login');
|
|
304
332
|
|
|
@@ -328,6 +356,7 @@ async function main() {
|
|
|
328
356
|
}
|
|
329
357
|
|
|
330
358
|
program
|
|
359
|
+
.version(cliVersion, '-v, --version', 'Display version number')
|
|
331
360
|
.option('-s, --session-id <id>', 'Reuse existing session ID')
|
|
332
361
|
.option('-l, --local', 'Use localhost (web: 3000, socket: 3001)')
|
|
333
362
|
.option('--web <url>', 'Web server URL (e.g., http://localhost:3000)')
|
|
@@ -348,10 +377,13 @@ async function main() {
|
|
|
348
377
|
|
|
349
378
|
// Auto-claim session if token is available and fetch auth code
|
|
350
379
|
let authCode = null;
|
|
351
|
-
if (token
|
|
352
|
-
//
|
|
380
|
+
if (token) {
|
|
381
|
+
// Try to claim session (works for both new and existing sessions)
|
|
382
|
+
// For new sessions, this will create and claim
|
|
383
|
+
// For existing sessions, this will return the auth code if user owns it
|
|
353
384
|
authCode = await claimSession(sessionId, token, webUrl);
|
|
354
|
-
if (authCode) {
|
|
385
|
+
if (authCode && !options.sessionId) {
|
|
386
|
+
// Only show claim message for new sessions
|
|
355
387
|
console.log(' ✓ Session automatically claimed to your account\n');
|
|
356
388
|
}
|
|
357
389
|
}
|
|
@@ -365,7 +397,7 @@ async function main() {
|
|
|
365
397
|
const localFlag = webUrl.includes('localhost') ? ' --local' : '';
|
|
366
398
|
const sessionSlug = sessionId.replace(/^vibex-/, ''); // Remove prefix for example
|
|
367
399
|
console.log(' 💡 Tip: Use -s to send more logs to this session');
|
|
368
|
-
console.log(` Example: echo '{"cpu": 45, "memory": 78
|
|
400
|
+
console.log(` Example: echo '{"cpu": 45, "memory": 78}' | npx vibex-sh -s ${sessionSlug}${localFlag}\n`);
|
|
369
401
|
} else {
|
|
370
402
|
// When reusing a session, show minimal info
|
|
371
403
|
const dashboardUrl = authCode
|
|
@@ -417,11 +449,15 @@ async function main() {
|
|
|
417
449
|
|
|
418
450
|
// Listen for auth code from socket.io (for unclaimed sessions)
|
|
419
451
|
socket.on('session-auth-code', (data) => {
|
|
420
|
-
if (data.sessionId === sessionId && data.authCode
|
|
421
|
-
|
|
422
|
-
//
|
|
423
|
-
|
|
424
|
-
|
|
452
|
+
if (data.sessionId === sessionId && data.authCode) {
|
|
453
|
+
// Always update and display auth code if received from socket
|
|
454
|
+
// This ensures we show it even if we didn't get it from claimSession
|
|
455
|
+
if (!receivedAuthCode || receivedAuthCode !== data.authCode) {
|
|
456
|
+
receivedAuthCode = data.authCode;
|
|
457
|
+
// Display auth code when received (for both new and existing sessions)
|
|
458
|
+
console.log(` 🔑 Auth Code: ${receivedAuthCode}`);
|
|
459
|
+
console.log(` 📋 Dashboard: ${webUrl}/${sessionId}?auth=${receivedAuthCode}\n`);
|
|
460
|
+
}
|
|
425
461
|
}
|
|
426
462
|
});
|
|
427
463
|
|
|
@@ -473,6 +509,48 @@ async function main() {
|
|
|
473
509
|
}
|
|
474
510
|
});
|
|
475
511
|
|
|
512
|
+
// Handle rate limit errors from server
|
|
513
|
+
socket.on('rate-limit-exceeded', (data) => {
|
|
514
|
+
console.error('\n ⚠️ Rate Limit Exceeded');
|
|
515
|
+
console.error(` ${data.message || 'Too many requests. Please try again later.'}`);
|
|
516
|
+
if (data.rateLimit) {
|
|
517
|
+
const { limit, remaining, resetAt, windowSeconds } = data.rateLimit;
|
|
518
|
+
if (limit !== undefined) {
|
|
519
|
+
console.error(` Limit: ${limit} requests`);
|
|
520
|
+
}
|
|
521
|
+
if (remaining !== undefined) {
|
|
522
|
+
console.error(` Remaining: ${remaining} requests`);
|
|
523
|
+
}
|
|
524
|
+
if (resetAt) {
|
|
525
|
+
const resetDate = new Date(resetAt);
|
|
526
|
+
const now = new Date();
|
|
527
|
+
const secondsUntilReset = Math.ceil((resetDate - now) / 1000);
|
|
528
|
+
if (secondsUntilReset > 0) {
|
|
529
|
+
console.error(` Resets in: ${secondsUntilReset} seconds`);
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
console.error('');
|
|
534
|
+
// Don't exit - let user decide, but clear the queue
|
|
535
|
+
logQueue.length = 0;
|
|
536
|
+
});
|
|
537
|
+
|
|
538
|
+
// Handle general errors from server
|
|
539
|
+
socket.on('error', (data) => {
|
|
540
|
+
console.error('\n ✗ Server Error');
|
|
541
|
+
if (typeof data === 'string') {
|
|
542
|
+
console.error(` ${data}`);
|
|
543
|
+
} else if (data && data.message) {
|
|
544
|
+
console.error(` ${data.message}`);
|
|
545
|
+
if (data.error) {
|
|
546
|
+
console.error(` Error: ${data.error}`);
|
|
547
|
+
}
|
|
548
|
+
} else {
|
|
549
|
+
console.error(' An unexpected error occurred');
|
|
550
|
+
}
|
|
551
|
+
console.error('');
|
|
552
|
+
});
|
|
553
|
+
|
|
476
554
|
const rl = readline.createInterface({
|
|
477
555
|
input: process.stdin,
|
|
478
556
|
output: process.stdout,
|