@7nsane/zift 1.0.5 → 1.0.6

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.
Files changed (2) hide show
  1. package/bin/zift.js +18 -44
  2. package/package.json +3 -1
package/bin/zift.js CHANGED
@@ -27,7 +27,7 @@ async function main() {
27
27
 
28
28
  if (args.includes('--zift')) {
29
29
  isInstallMode = true;
30
- target = args.find(a => !a.startsWith('-') && !['install', 'i'].includes(a)) || '.';
30
+ target = args.find(a => !a.startsWith('-') && !['install', 'i', 'npm'].includes(a)) || '.';
31
31
  }
32
32
 
33
33
  // 3. Flags
@@ -38,7 +38,7 @@ async function main() {
38
38
  }
39
39
  }
40
40
 
41
- // 4. No Args? Show Help or offer Setup
41
+ // 4. No Args? Show Help
42
42
  if (args.length === 0) {
43
43
  showHelp();
44
44
  return;
@@ -57,9 +57,9 @@ async function main() {
57
57
  async function runSetup() {
58
58
  const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
59
59
  console.log(chalk.blue.bold('\nšŸ›”ļø Zift Secure Alias Setup'));
60
- console.log(chalk.gray('This will allow you to use `npm install <pkg> --zift` for secure audits.\n'));
60
+ console.log(chalk.gray('Configure `npm install --zift` for automatic security audits.\n'));
61
61
 
62
- const question = chalk.white('Would you like to add the Zift secure alias to your shell profile? (y/n): ');
62
+ const question = chalk.white('Add the Zift secure wrapper to your shell profile? (y/n): ');
63
63
 
64
64
  rl.question(question, (answer) => {
65
65
  rl.close();
@@ -70,35 +70,32 @@ async function runSetup() {
70
70
  } else {
71
71
  setupUnix();
72
72
  }
73
- console.log(chalk.green('\nāœ… Setup complete! Please RESTART your terminal to use the new command.'));
73
+ console.log(chalk.green('\nāœ… Setup complete! Please RESTART your terminal.'));
74
+ console.log(chalk.gray('Try: npm install <pkg> --zift'));
74
75
  } catch (e) {
75
76
  console.error(chalk.red('\nāŒ Setup failed: ') + e.message);
76
77
  }
77
78
  } else {
78
- console.log(chalk.yellow('\nSetup cancelled. You can always run `zift setup` later.'));
79
+ console.log(chalk.yellow('\nSetup cancelled.'));
79
80
  }
80
81
  });
81
82
  }
82
83
 
83
84
  function setupWindows() {
84
- // Define PowerShell function
85
85
  const psFunction = `
86
86
  # Zift Secure Alias
87
- function npm-secure {
87
+ function npm {
88
88
  if ($args -contains "--zift") {
89
89
  $pkg = $args | Where-Object { $_ -ne "install" -and $_ -ne "i" -and $_ -ne "--zift" } | Select-Object -First 1
90
- npx @7nsane/zift install $pkg
90
+ Write-Host "\nšŸ›”ļø Zift: Intercepting installation for audit...\n" -ForegroundColor Green
91
+ npx @7nsane/zift@latest install $pkg
91
92
  } else {
92
- npm.cmd @args
93
+ & (Get-Command npm.cmd).Definition @args
93
94
  }
94
95
  }
95
- if (!(Test-Path alias:npm)) { Set-Alias npm npm-secure -Force -Scope Global }
96
96
  `;
97
-
98
- // Get PS Profile path
99
97
  const profilePath = cp.execSync('powershell -NoProfile -Command "echo $PROFILE"').toString().trim();
100
98
  const profileDir = path.dirname(profilePath);
101
-
102
99
  if (!fs.existsSync(profileDir)) fs.mkdirSync(profileDir, { recursive: true });
103
100
  fs.appendFileSync(profilePath, psFunction);
104
101
  }
@@ -109,7 +106,7 @@ function setupUnix() {
109
106
  npm() {
110
107
  if [[ "$*" == *"--zift"* ]]; then
111
108
  pkg=$(echo "$@" | sed 's/install//g; s/ i //g; s/--zift//g' | xargs)
112
- npx @7nsane/zift install $pkg
109
+ npx @7nsane/zift@latest install $pkg
113
110
  else
114
111
  command npm "$@"
115
112
  fi
@@ -117,18 +114,12 @@ npm() {
117
114
  `;
118
115
  const home = os.homedir();
119
116
  const profiles = [path.join(home, '.bashrc'), path.join(home, '.zshrc')];
120
-
121
- profiles.forEach(p => {
122
- if (fs.existsSync(p)) {
123
- fs.appendFileSync(p, bashFunction);
124
- }
125
- });
117
+ profiles.forEach(p => { if (fs.existsSync(p)) fs.appendFileSync(p, bashFunction); });
126
118
  }
127
119
 
128
120
  async function runLocalScan(targetDir, format) {
129
121
  const scanner = new PackageScanner(targetDir);
130
122
  if (format === 'text') console.log(chalk.blue(`\nšŸ” Scanning local directory: ${path.resolve(targetDir)}`));
131
-
132
123
  try {
133
124
  const findings = await scanner.scan();
134
125
  handleFindings(findings, format, targetDir);
@@ -138,12 +129,10 @@ async function runLocalScan(targetDir, format) {
138
129
  async function runRemoteAudit(packageName, format, installOnSuccess) {
139
130
  if (format === 'text') console.log(chalk.blue(`\nšŸŒ Remote Audit: Pre-scanning package '${packageName}'...`));
140
131
  const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'zift-audit-'));
141
-
142
132
  try {
143
133
  cp.execSync(`npm pack ${packageName}`, { cwd: tmpDir, stdio: 'ignore' });
144
134
  const tarball = fs.readdirSync(tmpDir).find(f => f.endsWith('.tgz'));
145
135
  cp.execSync(`tar -xzf ${tarball}`, { cwd: tmpDir });
146
-
147
136
  const scanPath = path.join(tmpDir, 'package');
148
137
  const scanner = new PackageScanner(scanPath);
149
138
  const findings = await scanner.scan();
@@ -165,14 +154,12 @@ async function runRemoteAudit(packageName, format, installOnSuccess) {
165
154
  cleanupAndExit(tmpDir, 0);
166
155
  });
167
156
  } else { cleanupAndExit(tmpDir, 0); }
168
- } catch (err) {
169
- cleanupAndExit(tmpDir, 1);
170
- }
157
+ } catch (err) { cleanupAndExit(tmpDir, 1); }
171
158
  }
172
159
 
173
160
  function handleFindings(findings, format, targetDir, skipExit = false) {
174
161
  if (format === 'json') {
175
- process.stdout.write(JSON.stringify({ target: targetDir, findings, summary: getSummary(findings) }, null, 2));
162
+ process.stdout.write(JSON.stringify({ target: targetDir, findings, summary: { Critical: findings.filter(f => f.classification === 'Critical').length, High: findings.filter(f => f.classification === 'High').length, Medium: findings.filter(f => f.classification === 'Medium').length, Low: findings.filter(f => f.classification === 'Low').length } }, null, 2));
176
163
  if (!skipExit) process.exit(findings.some(f => f.score >= 90) ? 1 : 0);
177
164
  return;
178
165
  }
@@ -186,16 +173,15 @@ function handleFindings(findings, format, targetDir, skipExit = false) {
186
173
  f.triggers.forEach(t => console.log(chalk.white(` - ${t.type} in ${t.file}:${t.line} [${t.context}]`)));
187
174
  console.log('');
188
175
  });
189
- printSummary(findings);
190
176
  if (!skipExit) process.exit(findings[0].score >= 90 ? 1 : 0);
191
177
  }
192
178
 
193
179
  function showHelp() {
194
180
  console.log(chalk.blue.bold('\nšŸ›”ļø Zift - The Elite Security Scanner\n'));
195
181
  console.log('Usage:');
196
- console.log(' zift setup Configure secure npm aliases');
197
- console.log(' zift install <pkg> Scan and prompt before installing');
198
- console.log(' zift . Scan current directory');
182
+ console.log(' zift setup Configure secure npm wrapper');
183
+ console.log(' zift install <pkg> Audit and install package');
184
+ console.log(' zift . Scan local directory');
199
185
  }
200
186
 
201
187
  function cleanupAndExit(dir, code) {
@@ -208,16 +194,4 @@ function handleError(err, format) {
208
194
  process.exit(1);
209
195
  }
210
196
 
211
- function getSummary(findings) {
212
- const s = { Critical: 0, High: 0, Medium: 0, Low: 0 };
213
- findings.forEach(f => s[f.classification]++);
214
- return s;
215
- }
216
-
217
- function printSummary(findings) {
218
- const s = getSummary(findings);
219
- console.log(chalk.bold('Severity Summary:'));
220
- console.log(chalk.red(` Critical: ${s.Critical}\n High: ${s.High}`));
221
- }
222
-
223
197
  main();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@7nsane/zift",
3
- "version": "1.0.5",
3
+ "version": "1.0.6",
4
4
  "description": "A high-performance, deterministic security scanner for npm packages.",
5
5
  "main": "src/scanner.js",
6
6
  "bin": {
@@ -24,7 +24,9 @@
24
24
  "dependencies": {
25
25
  "acorn": "^8.16.0",
26
26
  "acorn-walk": "^8.3.5",
27
+ "axios": "^1.13.6",
27
28
  "chalk": "^4.1.2",
29
+ "express": "^5.2.1",
28
30
  "glob": "^13.0.6"
29
31
  }
30
32
  }