vibe-audit-scan 1.2.10 → 1.2.12

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/bin/vibe-audit.js CHANGED
@@ -2,13 +2,37 @@
2
2
  import { program } from 'commander';
3
3
  import chalk from 'chalk';
4
4
  import boxen from 'boxen';
5
+ import fs from 'fs-extra';
6
+ import path from 'path';
7
+ import os from 'os';
8
+ import { fileURLToPath } from 'url';
5
9
  import { scan } from '../src/commands/scan.js';
6
10
  import { login, logout, whoami } from '../src/commands/auth.js';
7
11
  import { printWelcome, printHelpCheatsheet } from '../src/utils/welcome.js';
8
12
 
13
+ const __filename = fileURLToPath(import.meta.url);
14
+ const __dirname = path.dirname(__filename);
15
+ const pkg = fs.readJsonSync(path.join(__dirname, '..', 'package.json'));
16
+ const version = pkg.version;
17
+
18
+ const WELCOME_MARKER = path.join(os.homedir(), '.vibe-audit-scan', '.welcome_shown');
19
+
20
+ function checkFirstRunWelcome() {
21
+ try {
22
+ if (!fs.existsSync(WELCOME_MARKER)) {
23
+ printWelcome();
24
+ fs.ensureDirSync(path.dirname(WELCOME_MARKER));
25
+ fs.writeFileSync(WELCOME_MARKER, 'true');
26
+ console.log('\n' + '='.repeat(107) + '\n');
27
+ }
28
+ } catch (err) {
29
+ // Fail-silent to not block main execution
30
+ }
31
+ }
32
+
9
33
  program
10
34
  .name('vibe')
11
- .version('1.2.6', '-V, --version', 'output the version number')
35
+ .version(version, '-V, --version', 'output the version number')
12
36
  .description('Vibe Audit CLI - Scan your codebase for vulnerabilities')
13
37
  .configureOutput({
14
38
  writeOut: (str) => {
@@ -102,8 +126,14 @@ program
102
126
 
103
127
  // Handle vibe without command - show welcome screen
104
128
  if (process.argv.length <= 2) {
129
+ try {
130
+ fs.ensureDirSync(path.dirname(WELCOME_MARKER));
131
+ fs.writeFileSync(WELCOME_MARKER, 'true');
132
+ } catch (err) {}
105
133
  printWelcome();
106
134
  process.exit(0);
135
+ } else {
136
+ checkFirstRunWelcome();
107
137
  }
108
138
 
109
139
  program.parse();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vibe-audit-scan",
3
- "version": "1.2.10",
3
+ "version": "1.2.12",
4
4
  "type": "module",
5
5
  "license": "UNLICENSED",
6
6
  "author": "Vibe Audit",
@@ -10,7 +10,7 @@
10
10
  "vibe-audit-scan": "./bin/vibe-audit.js"
11
11
  },
12
12
  "scripts": {
13
- "postinstall": "node -e \"console.log('\\n\\nšŸŽ‰ Vibe Audit CLI installed successfully!\\n\\nšŸš€ Run \\\"vibe scan\\\" inside your project folder to start scanning.\\n\\n')\""
13
+ "postinstall": "node ./bin/vibe-audit.js"
14
14
  },
15
15
  "dependencies": {
16
16
  "adm-zip": "^0.5.17",
@@ -89,13 +89,57 @@ async function installLocalTrivy() {
89
89
 
90
90
  // Download the asset
91
91
  console.log(`šŸ“„ Downloading scanner updates v${latestVersion}...`);
92
- const downloadRes = await axios.get(asset.browser_download_url, {
93
- responseType: 'arraybuffer'
92
+ const tempPath = path.join(os.tmpdir(), `trivy_${latestVersion}.${ext}`);
93
+ const writer = fs.createWriteStream(tempPath);
94
+
95
+ const response = await axios({
96
+ url: asset.browser_download_url,
97
+ method: 'GET',
98
+ responseType: 'stream',
99
+ timeout: 30000 // 30s connection timeout
94
100
  });
95
101
 
96
- // Create temp file
97
- const tempPath = path.join(os.tmpdir(), `trivy_${latestVersion}.${ext}`);
98
- await fs.writeFile(tempPath, downloadRes.data);
102
+ const totalLength = parseInt(response.headers['content-length'], 10) || 0;
103
+ let downloadedBytes = 0;
104
+ let lastPercentage = -10;
105
+
106
+ response.data.pipe(writer);
107
+
108
+ let downloadTimeout = setTimeout(() => {
109
+ response.data.destroy();
110
+ writer.destroy();
111
+ }, 60000); // 60s inactivity timeout
112
+
113
+ response.data.on('data', (chunk) => {
114
+ // Reset inactivity timeout
115
+ clearTimeout(downloadTimeout);
116
+ downloadTimeout = setTimeout(() => {
117
+ response.data.destroy();
118
+ writer.destroy();
119
+ }, 60000);
120
+
121
+ downloadedBytes += chunk.length;
122
+ if (totalLength > 0) {
123
+ const percentage = Math.floor((downloadedBytes / totalLength) * 10);
124
+ if (percentage > lastPercentage) {
125
+ lastPercentage = percentage;
126
+ console.log(`šŸ“„ Download progress: ${percentage * 10}% (${(downloadedBytes / 1024 / 1024).toFixed(1)}MB / ${(totalLength / 1024 / 1024).toFixed(1)}MB)...`);
127
+ }
128
+ } else {
129
+ console.log(`šŸ“„ Downloaded ${(downloadedBytes / 1024 / 1024).toFixed(1)}MB...`);
130
+ }
131
+ });
132
+
133
+ await new Promise((resolve, reject) => {
134
+ writer.on('finish', () => {
135
+ clearTimeout(downloadTimeout);
136
+ resolve();
137
+ });
138
+ writer.on('error', (err) => {
139
+ clearTimeout(downloadTimeout);
140
+ reject(err);
141
+ });
142
+ });
99
143
 
100
144
  // Extract the binary
101
145
  console.log('šŸ“¦ Extracting scanner components...');
@@ -1,5 +1,13 @@
1
1
  import chalk from 'chalk';
2
2
  import boxen from 'boxen';
3
+ import fs from 'fs-extra';
4
+ import path from 'path';
5
+ import { fileURLToPath } from 'url';
6
+
7
+ const __filename = fileURLToPath(import.meta.url);
8
+ const __dirname = path.dirname(__filename);
9
+ const pkg = fs.readJsonSync(path.join(__dirname, '..', '..', 'package.json'));
10
+ const version = pkg.version;
3
11
 
4
12
  const asciiArt = [
5
13
  'ā–ˆā–ˆā–ˆā–ˆā–ˆ ā–ˆā–ˆā–ˆā–ˆā–ˆ ā–ˆā–ˆā–ˆā–ˆā–ˆ ā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆ ā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆ ā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆ ā–ˆā–ˆā–ˆā–ˆā–ˆ ā–ˆā–ˆā–ˆā–ˆā–ˆ ā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆ ā–ˆā–ˆā–ˆā–ˆā–ˆ ā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆ ',
@@ -12,60 +20,89 @@ const asciiArt = [
12
20
  ' ā–‘ā–‘ā–‘ ā–‘ā–‘ā–‘ā–‘ā–‘ ā–‘ā–‘ā–‘ā–‘ā–‘ā–‘ā–‘ā–‘ā–‘ā–‘ā–‘ ā–‘ā–‘ā–‘ā–‘ā–‘ā–‘ā–‘ā–‘ā–‘ā–‘ ā–‘ā–‘ā–‘ā–‘ā–‘ ā–‘ā–‘ā–‘ā–‘ā–‘ ā–‘ā–‘ā–‘ā–‘ā–‘ā–‘ā–‘ā–‘ ā–‘ā–‘ā–‘ā–‘ā–‘ā–‘ā–‘ā–‘ā–‘ā–‘ ā–‘ā–‘ā–‘ā–‘ā–‘ ā–‘ā–‘ā–‘ā–‘ā–‘ '
13
21
  ];
14
22
 
23
+ function getColors() {
24
+ const isLight = (() => {
25
+ if (process.env.COLORFGBG) {
26
+ const parts = process.env.COLORFGBG.split(';');
27
+ if (parts.length > 1) {
28
+ const bg = parseInt(parts[parts.length - 1], 10);
29
+ return bg === 7 || bg === 15 || bg > 10;
30
+ }
31
+ }
32
+ if (process.env.ITERM_PROFILE && process.env.ITERM_PROFILE.toLowerCase().includes('light')) {
33
+ return true;
34
+ }
35
+ return false;
36
+ })();
37
+
38
+ return {
39
+ brand: isLight ? chalk.blue : chalk.cyan,
40
+ brandBold: isLight ? chalk.blue.bold : chalk.cyan.bold,
41
+ text: isLight ? chalk.black : chalk.white,
42
+ textBold: isLight ? chalk.black.bold : chalk.white.bold,
43
+ muted: isLight ? chalk.blue.dim : chalk.gray,
44
+ border: isLight ? 'blue' : 'cyan'
45
+ };
46
+ }
47
+
15
48
  export function printWelcome() {
49
+ const colors = getColors();
50
+
16
51
  // Print ASCII art first
17
52
  console.log('');
18
53
  asciiArt.forEach(line => {
19
- console.log(chalk.cyan(line));
54
+ console.log(colors.brand(line));
20
55
  });
21
56
  console.log('');
22
57
 
23
58
  const welcomeContent = `
24
- ${chalk.cyan.bold('Vibe Audit')}${chalk.gray(' v1.2.6 | Terminal-First Security')}
25
- ${chalk.gray('-'.repeat(50))}
59
+ ${colors.brandBold('Vibe Audit')}${colors.muted(` v${version} | Terminal-First Security`)}
60
+ ${colors.muted('-'.repeat(50))}
26
61
 
27
- ${chalk.white.bold('šŸš€ Ready to secure your code?')}
62
+ ${colors.textBold('šŸš€ Ready to secure your code?')}
28
63
 
29
- ${chalk.cyan.bold('Quick Start:')}
30
- ${chalk.gray('$')} ${chalk.white('vibe scan .')}${chalk.gray(' # Scan current directory')}
31
- ${chalk.gray('$')} ${chalk.white('vibe login')}${chalk.gray(' # Authenticate your account')}
64
+ ${colors.brandBold('Quick Start:')}
65
+ ${colors.muted('$')} ${colors.text('vibe scan .')}${colors.muted(' # Scan current directory')}
66
+ ${colors.muted('$')} ${colors.text('vibe login')}${colors.muted(' # Authenticate your account')}
32
67
 
33
- ${chalk.cyan.bold('Need help?')}
34
- ${chalk.gray('$')} ${chalk.white('vibe --help')}${chalk.gray(' # View all available commands')}
35
- ${chalk.gray('$')} ${chalk.white('vibe cheatsheet')}${chalk.gray(' # List shortcuts and status')}
68
+ ${colors.brandBold('Need help?')}
69
+ ${colors.muted('$')} ${colors.text('vibe --help')}${colors.muted(' # View all available commands')}
70
+ ${colors.muted('$')} ${colors.text('vibe cheatsheet')}${colors.muted(' # List shortcuts and status')}
36
71
  `;
37
72
 
38
73
  console.log(boxen(welcomeContent, {
39
74
  padding: 1,
40
75
  margin: 1,
41
76
  borderStyle: 'round',
42
- borderColor: 'cyan',
77
+ borderColor: colors.border,
43
78
  titleAlignment: 'left'
44
79
  }));
45
80
  }
46
81
 
47
82
  export function printHelpCheatsheet() {
83
+ const colors = getColors();
84
+
48
85
  const cheatsheet = `
49
- ${chalk.cyan.bold('Vibe Audit Command Cheatsheet')}
86
+ ${colors.brandBold('Vibe Audit Command Cheatsheet')}
50
87
 
51
- ${chalk.white.bold('Auth Commands:')}
52
- ${chalk.white('vibe login')}${chalk.gray(' - Authenticate your CLI with the Vibe Cloud backend')}
53
- ${chalk.white('vibe whoami')}${chalk.gray(' - Displays the currently logged-in user profile')}
54
- ${chalk.white('vibe logout')}${chalk.gray(' - Revokes your session and clears local tokens')}
88
+ ${colors.textBold('Auth Commands:')}
89
+ ${colors.text('vibe login')}${colors.muted(' - Authenticate your CLI with the Vibe Cloud backend')}
90
+ ${colors.text('vibe whoami')}${colors.muted(' - Displays the currently logged-in user profile')}
91
+ ${colors.text('vibe logout')}${colors.muted(' - Revokes your session and clears local tokens')}
55
92
 
56
- ${chalk.white.bold('Scan Commands:')}
57
- ${chalk.white('vibe scan <dir>')}${chalk.gray(' - Scans a directory and sends results to the AI engine')}
58
- ${chalk.white('vibe status <id>')}${chalk.gray(' - Checks the real-time processing status of an audit')}
93
+ ${colors.textBold('Scan Commands:')}
94
+ ${colors.text('vibe scan <dir>')}${colors.muted(' - Scans a directory and sends results to the AI engine')}
95
+ ${colors.text('vibe status <id>')}${colors.muted(' - Checks the real-time processing status of an audit')}
59
96
 
60
- ${chalk.white.bold('System Commands:')}
61
- ${chalk.white('vibe cheatsheet')}${chalk.gray(' - Lists all commands and current system status')}
62
- ${chalk.white('vibe install-deps')}${chalk.gray(' - Auto-installs/verifies Trivy binary dependencies')}
97
+ ${colors.textBold('System Commands:')}
98
+ ${colors.text('vibe cheatsheet')}${colors.muted(' - Lists all commands and current system status')}
99
+ ${colors.text('vibe install-deps')}${colors.muted(' - Auto-installs/verifies Trivy binary dependencies')}
63
100
  `;
64
101
 
65
102
  console.log(boxen(cheatsheet, {
66
103
  padding: 1,
67
104
  margin: 1,
68
105
  borderStyle: 'round',
69
- borderColor: 'cyan'
106
+ borderColor: colors.border
70
107
  }));
71
108
  }