vibex-sh 0.9.2 → 0.9.3
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 +211 -57
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -29,12 +29,11 @@ try {
|
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
// Session ID generation is now handled by the server
|
|
33
|
+
// This function is kept for backward compatibility but should not be used for new sessions
|
|
34
34
|
function generateSessionId() {
|
|
35
|
-
//
|
|
36
|
-
//
|
|
37
|
-
// Using crypto for better randomness
|
|
35
|
+
// DEPRECATED: Session IDs should be generated by the server
|
|
36
|
+
// This is only used as a fallback if server creation fails
|
|
38
37
|
const chars = 'abcdefghijklmnopqrstuvwxyz0123456789';
|
|
39
38
|
let result = 'vibex-';
|
|
40
39
|
|
|
@@ -370,41 +369,63 @@ async function main() {
|
|
|
370
369
|
.parse();
|
|
371
370
|
|
|
372
371
|
const options = program.opts();
|
|
373
|
-
|
|
374
|
-
// Normalize session ID - add 'vibex-' prefix if missing
|
|
375
|
-
const rawSessionId = options.sessionId || generateSessionId();
|
|
376
|
-
const sessionId = normalizeSessionId(rawSessionId);
|
|
377
372
|
const { webUrl, socketUrl } = getUrls(options);
|
|
378
373
|
|
|
379
374
|
// Get token from flag, env var, or stored config
|
|
380
375
|
let token = options.token || process.env.VIBEX_TOKEN || await getStoredToken();
|
|
381
376
|
|
|
382
|
-
|
|
377
|
+
let sessionId;
|
|
383
378
|
let authCode = null;
|
|
384
|
-
if (token) {
|
|
385
|
-
// Try to claim session (works for both new and existing sessions)
|
|
386
|
-
// For new sessions, this will create and claim
|
|
387
|
-
// For existing sessions, this will return the auth code if user owns it
|
|
388
|
-
authCode = await claimSession(sessionId, token, webUrl);
|
|
389
|
-
if (authCode && !options.sessionId) {
|
|
390
|
-
// Only show claim message for new sessions
|
|
391
|
-
console.log(' ✓ Session automatically claimed to your account\n');
|
|
392
|
-
}
|
|
393
|
-
}
|
|
394
379
|
|
|
395
|
-
//
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
} else {
|
|
406
|
-
// When reusing a session, show minimal info (no auth code)
|
|
380
|
+
// If session ID is provided, use it (existing session)
|
|
381
|
+
if (options.sessionId) {
|
|
382
|
+
sessionId = normalizeSessionId(options.sessionId);
|
|
383
|
+
|
|
384
|
+
// If token is available, try to claim the session
|
|
385
|
+
if (token) {
|
|
386
|
+
authCode = await claimSession(sessionId, token, webUrl);
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
// When reusing a session, show minimal info
|
|
407
390
|
console.log(` 🔍 Sending logs to session: ${sessionId}\n`);
|
|
391
|
+
} else {
|
|
392
|
+
// No session ID provided - create a new anonymous session
|
|
393
|
+
try {
|
|
394
|
+
const createUrl = `${webUrl}/api/sessions/create-anonymous`;
|
|
395
|
+
const response = await httpRequest(createUrl, {
|
|
396
|
+
method: 'POST',
|
|
397
|
+
headers: { 'Content-Type': 'application/json' },
|
|
398
|
+
});
|
|
399
|
+
|
|
400
|
+
if (!response.ok) {
|
|
401
|
+
const errorData = await response.json();
|
|
402
|
+
console.error(` ✗ Failed to create session: ${errorData.message || 'Unknown error'}`);
|
|
403
|
+
process.exit(1);
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
const data = await response.json();
|
|
407
|
+
sessionId = data.sessionId; // Server-generated unique session ID
|
|
408
|
+
authCode = data.authCode; // Server-generated auth code
|
|
409
|
+
|
|
410
|
+
// If token is available, claim the session
|
|
411
|
+
if (token) {
|
|
412
|
+
const claimAuthCode = await claimSession(sessionId, token, webUrl);
|
|
413
|
+
if (claimAuthCode) {
|
|
414
|
+
authCode = claimAuthCode;
|
|
415
|
+
console.log(' ✓ Session automatically claimed to your account\n');
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
// Print banner for new session
|
|
420
|
+
printBanner(sessionId, webUrl, authCode);
|
|
421
|
+
const localFlag = webUrl.includes('localhost') ? ' --local' : '';
|
|
422
|
+
const sessionSlug = sessionId.replace(/^vibex-/, ''); // Remove prefix for example
|
|
423
|
+
console.log(' 💡 Tip: Use -s to send more logs to this session');
|
|
424
|
+
console.log(` Example: echo '{"cpu": 45, "memory": 78}' | npx vibex-sh -s ${sessionSlug}${localFlag}\n`);
|
|
425
|
+
} catch (error: any) {
|
|
426
|
+
console.error(` ✗ Error creating session: ${error.message}`);
|
|
427
|
+
process.exit(1);
|
|
428
|
+
}
|
|
408
429
|
}
|
|
409
430
|
|
|
410
431
|
let socket = null;
|
|
@@ -475,14 +496,22 @@ async function main() {
|
|
|
475
496
|
break;
|
|
476
497
|
|
|
477
498
|
case 'error':
|
|
478
|
-
|
|
499
|
+
const errorType = message.error || 'Error';
|
|
500
|
+
const errorMsg = message.message || 'An unexpected error occurred';
|
|
501
|
+
const statusCode = message.statusCode || 0;
|
|
502
|
+
|
|
503
|
+
// Handle specific error types
|
|
504
|
+
if (errorType === 'Rate Limit Exceeded' || statusCode === 429) {
|
|
479
505
|
console.error('\n ⚠️ Rate Limit Exceeded');
|
|
480
|
-
console.error(` ${
|
|
506
|
+
console.error(` ${errorMsg}`);
|
|
507
|
+
if (message.retryAfter) {
|
|
508
|
+
console.error(` ⏱️ Retry after: ${message.retryAfter} seconds`);
|
|
509
|
+
}
|
|
481
510
|
console.error('');
|
|
482
511
|
logQueue.length = 0;
|
|
483
|
-
} else if (
|
|
512
|
+
} else if (errorType === 'History Limit Reached' || (statusCode === 403 && errorMsg.includes('History Limit'))) {
|
|
484
513
|
console.error('\n 🚫 History Limit Reached');
|
|
485
|
-
console.error(` ${
|
|
514
|
+
console.error(` ${errorMsg}`);
|
|
486
515
|
if (message.limit !== undefined && message.current !== undefined) {
|
|
487
516
|
console.error(` Current: ${message.current} / ${message.limit} logs`);
|
|
488
517
|
}
|
|
@@ -493,10 +522,69 @@ async function main() {
|
|
|
493
522
|
console.error('');
|
|
494
523
|
logQueue.length = 0;
|
|
495
524
|
hasJoinedSession = false;
|
|
525
|
+
} else if (statusCode === 401 || errorType === 'Unauthorized') {
|
|
526
|
+
if (errorMsg.includes('expired')) {
|
|
527
|
+
console.error('\n 🔑 Token Expired');
|
|
528
|
+
console.error(' Your authentication token has expired.');
|
|
529
|
+
console.error(' 💡 Run: npx vibex-sh login');
|
|
530
|
+
} else {
|
|
531
|
+
console.error('\n 🔑 Unauthorized');
|
|
532
|
+
console.error(` ${errorMsg}`);
|
|
533
|
+
console.error(' 💡 Run: npx vibex-sh login');
|
|
534
|
+
}
|
|
535
|
+
console.error('');
|
|
536
|
+
logQueue.length = 0;
|
|
537
|
+
hasJoinedSession = false;
|
|
538
|
+
} else if (statusCode === 403 || errorType === 'Forbidden') {
|
|
539
|
+
if (errorMsg.includes('access') || errorMsg.includes('belongs')) {
|
|
540
|
+
console.error('\n 🚫 Access Denied');
|
|
541
|
+
console.error(` ${errorMsg}`);
|
|
542
|
+
console.error(' 💡 This session belongs to another user or is not accessible');
|
|
543
|
+
console.error(' 💡 Make sure you are using the correct token and session ID');
|
|
544
|
+
} else if (errorMsg.includes('archived')) {
|
|
545
|
+
console.error('\n 🚫 Session Archived');
|
|
546
|
+
console.error(` ${errorMsg}`);
|
|
547
|
+
console.error(' 💡 This session is archived and cannot accept new logs');
|
|
548
|
+
} else {
|
|
549
|
+
console.error('\n 🚫 Forbidden');
|
|
550
|
+
console.error(` ${errorMsg}`);
|
|
551
|
+
}
|
|
552
|
+
console.error('');
|
|
553
|
+
logQueue.length = 0;
|
|
554
|
+
hasJoinedSession = false;
|
|
555
|
+
} else if (statusCode === 404 || errorType === 'Not Found') {
|
|
556
|
+
console.error('\n 🔍 Session Not Found');
|
|
557
|
+
console.error(` ${errorMsg}`);
|
|
558
|
+
console.error(' 💡 Make sure the session ID is correct');
|
|
559
|
+
console.error(' 💡 Check if the session exists in your dashboard');
|
|
560
|
+
console.error('');
|
|
561
|
+
logQueue.length = 0;
|
|
562
|
+
hasJoinedSession = false;
|
|
563
|
+
} else if (statusCode === 400 || errorType === 'Bad Request') {
|
|
564
|
+
console.error('\n 📝 Bad Request');
|
|
565
|
+
console.error(` ${errorMsg}`);
|
|
566
|
+
if (errorMsg.includes('sessionId')) {
|
|
567
|
+
console.error(' 💡 Make sure you provided a valid session ID with -s or --session');
|
|
568
|
+
} else if (errorMsg.includes('logs')) {
|
|
569
|
+
console.error(' 💡 Make sure you are sending valid log data');
|
|
570
|
+
}
|
|
571
|
+
console.error('');
|
|
572
|
+
logQueue.length = 0;
|
|
573
|
+
} else if (statusCode >= 500 || errorType === 'Internal Server Error') {
|
|
574
|
+
console.error('\n 🔴 Server Error');
|
|
575
|
+
console.error(` ${errorMsg}`);
|
|
576
|
+
console.error(' 💡 This is a server-side issue. Please try again later.');
|
|
577
|
+
console.error(' 💡 If the problem persists, contact support');
|
|
578
|
+
console.error('');
|
|
579
|
+
logQueue.length = 0;
|
|
496
580
|
} else {
|
|
497
|
-
console.error('\n ✗
|
|
498
|
-
console.error(` ${
|
|
581
|
+
console.error('\n ✗ Error');
|
|
582
|
+
console.error(` ${errorType}: ${errorMsg}`);
|
|
583
|
+
if (statusCode) {
|
|
584
|
+
console.error(` Status Code: ${statusCode}`);
|
|
585
|
+
}
|
|
499
586
|
console.error('');
|
|
587
|
+
logQueue.length = 0;
|
|
500
588
|
}
|
|
501
589
|
break;
|
|
502
590
|
|
|
@@ -544,12 +632,8 @@ async function main() {
|
|
|
544
632
|
|
|
545
633
|
// Send logs via HTTP POST (non-blocking, same as SDKs)
|
|
546
634
|
// Use Cloudflare Worker endpoint (port 8787 for local, or Worker URL for production)
|
|
635
|
+
// Token is optional - anonymous sessions can send logs without authentication
|
|
547
636
|
const sendLogViaHTTP = async (logData) => {
|
|
548
|
-
if (!token) {
|
|
549
|
-
console.error(' ✗ No token available for sending logs');
|
|
550
|
-
return;
|
|
551
|
-
}
|
|
552
|
-
|
|
553
637
|
try {
|
|
554
638
|
// Determine ingest URL
|
|
555
639
|
let ingestUrl;
|
|
@@ -567,12 +651,17 @@ async function main() {
|
|
|
567
651
|
|
|
568
652
|
console.log(` 📤 Sending log to: ${ingestUrl}`);
|
|
569
653
|
|
|
654
|
+
// Build headers - only include Authorization if token exists
|
|
655
|
+
const headers = {
|
|
656
|
+
'Content-Type': 'application/json',
|
|
657
|
+
};
|
|
658
|
+
if (token) {
|
|
659
|
+
headers['Authorization'] = `Bearer ${token}`;
|
|
660
|
+
}
|
|
661
|
+
|
|
570
662
|
const response = await fetch(ingestUrl, {
|
|
571
663
|
method: 'POST',
|
|
572
|
-
headers
|
|
573
|
-
'Authorization': `Bearer ${token}`,
|
|
574
|
-
'Content-Type': 'application/json',
|
|
575
|
-
},
|
|
664
|
+
headers,
|
|
576
665
|
body: JSON.stringify({
|
|
577
666
|
sessionId,
|
|
578
667
|
logs: [logData],
|
|
@@ -581,19 +670,84 @@ async function main() {
|
|
|
581
670
|
|
|
582
671
|
if (!response.ok) {
|
|
583
672
|
const errorData = await response.json().catch(() => ({}));
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
673
|
+
const errorMessage = errorData.message || response.statusText || 'Unknown error';
|
|
674
|
+
|
|
675
|
+
console.error(`\n ✗ HTTP ${response.status}: ${errorMessage}`);
|
|
676
|
+
|
|
677
|
+
// Handle specific error cases
|
|
678
|
+
if (response.status === 401) {
|
|
679
|
+
if (errorMessage.includes('expired')) {
|
|
680
|
+
console.error('\n 🔑 Token Expired');
|
|
681
|
+
console.error(' Your authentication token has expired.');
|
|
682
|
+
console.error(' 💡 Run: npx vibex-sh login');
|
|
683
|
+
console.error('');
|
|
684
|
+
} else if (errorMessage.includes('Invalid') || errorMessage.includes('invalid')) {
|
|
685
|
+
console.error('\n 🔑 Invalid Token');
|
|
686
|
+
console.error(' Your authentication token is invalid or missing.');
|
|
687
|
+
console.error(' 💡 Run: npx vibex-sh login');
|
|
688
|
+
console.error('');
|
|
689
|
+
} else {
|
|
690
|
+
console.error('\n 🔑 Unauthorized');
|
|
691
|
+
console.error(` ${errorMessage}`);
|
|
692
|
+
console.error(' 💡 Run: npx vibex-sh login');
|
|
693
|
+
console.error('');
|
|
694
|
+
}
|
|
695
|
+
} else if (response.status === 400) {
|
|
696
|
+
console.error('\n 📝 Bad Request');
|
|
697
|
+
console.error(` ${errorMessage}`);
|
|
698
|
+
if (errorMessage.includes('sessionId')) {
|
|
699
|
+
console.error(' 💡 Make sure you provided a valid session ID with -s or --session');
|
|
700
|
+
} else if (errorMessage.includes('logs')) {
|
|
701
|
+
console.error(' 💡 Make sure you are sending valid log data');
|
|
702
|
+
}
|
|
703
|
+
console.error('');
|
|
704
|
+
} else if (response.status === 403) {
|
|
705
|
+
if (errorMessage.includes('History Limit')) {
|
|
706
|
+
console.error('\n 🚫 History Limit Reached');
|
|
707
|
+
console.error(` ${errorMessage}`);
|
|
708
|
+
if (errorData.upgradeRequired) {
|
|
709
|
+
console.error(' 💡 Upgrade to Pro to unlock 30 days retention');
|
|
710
|
+
console.error(' 🌐 Visit: https://vibex.sh/pricing');
|
|
711
|
+
}
|
|
712
|
+
console.error('');
|
|
713
|
+
} else if (errorMessage.includes('access') || errorMessage.includes('belongs')) {
|
|
714
|
+
console.error('\n 🚫 Access Denied');
|
|
715
|
+
console.error(` ${errorMessage}`);
|
|
716
|
+
console.error(' 💡 This session belongs to another user or is not accessible');
|
|
717
|
+
console.error(' 💡 Make sure you are using the correct token and session ID');
|
|
718
|
+
console.error('');
|
|
719
|
+
} else if (errorMessage.includes('archived')) {
|
|
720
|
+
console.error('\n 🚫 Session Archived');
|
|
721
|
+
console.error(` ${errorMessage}`);
|
|
722
|
+
console.error(' 💡 This session is archived and cannot accept new logs');
|
|
723
|
+
console.error('');
|
|
724
|
+
} else {
|
|
725
|
+
console.error('\n 🚫 Forbidden');
|
|
726
|
+
console.error(` ${errorMessage}`);
|
|
727
|
+
console.error('');
|
|
728
|
+
}
|
|
729
|
+
} else if (response.status === 404) {
|
|
730
|
+
console.error('\n 🔍 Session Not Found');
|
|
731
|
+
console.error(` ${errorMessage}`);
|
|
732
|
+
console.error(' 💡 Make sure the session ID is correct');
|
|
733
|
+
console.error(' 💡 Check if the session exists in your dashboard');
|
|
588
734
|
console.error('');
|
|
589
|
-
} else if (response.status ===
|
|
590
|
-
console.error('\n
|
|
591
|
-
console.error(` ${
|
|
592
|
-
if (errorData.
|
|
593
|
-
console.error(
|
|
594
|
-
console.error(' 🌐 Visit: https://vibex.sh/pricing');
|
|
735
|
+
} else if (response.status === 429) {
|
|
736
|
+
console.error('\n ⚠️ Rate Limit Exceeded');
|
|
737
|
+
console.error(` ${errorMessage}`);
|
|
738
|
+
if (errorData.retryAfter) {
|
|
739
|
+
console.error(` ⏱️ Retry after: ${errorData.retryAfter} seconds`);
|
|
595
740
|
}
|
|
596
741
|
console.error('');
|
|
742
|
+
} else if (response.status >= 500) {
|
|
743
|
+
console.error('\n 🔴 Server Error');
|
|
744
|
+
console.error(` ${errorMessage}`);
|
|
745
|
+
console.error(' 💡 This is a server-side issue. Please try again later.');
|
|
746
|
+
console.error(' 💡 If the problem persists, contact support');
|
|
747
|
+
console.error('');
|
|
748
|
+
} else {
|
|
749
|
+
console.error(` ${errorMessage}`);
|
|
750
|
+
console.error('');
|
|
597
751
|
}
|
|
598
752
|
} else {
|
|
599
753
|
const result = await response.json().catch(() => ({}));
|