proof-of-commitment 1.2.0 → 1.3.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.
- package/index.js +39 -9
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -140,11 +140,17 @@ ${clr(c.bold, 'Usage:')}
|
|
|
140
140
|
npx proof-of-commitment --file pnpm-lock.yaml Audit from pnpm lock file
|
|
141
141
|
npx proof-of-commitment --file requirements.txt Audit Python packages
|
|
142
142
|
|
|
143
|
+
${clr(c.bold, 'Options:')}
|
|
144
|
+
--json Output results as JSON (exits 1 if any CRITICAL found — useful in CI)
|
|
145
|
+
--pypi Score PyPI packages instead of npm
|
|
146
|
+
--file, -f Read packages from package.json, lock file, or requirements.txt
|
|
147
|
+
|
|
143
148
|
${clr(c.bold, 'Examples:')}
|
|
144
149
|
npx proof-of-commitment axios zod chalk
|
|
145
150
|
npx proof-of-commitment --pypi litellm langchain requests
|
|
146
151
|
npx proof-of-commitment --file package.json
|
|
147
152
|
npx proof-of-commitment --file package-lock.json # scans ALL transitive deps
|
|
153
|
+
npx proof-of-commitment axios chalk --json | jq '.criticalCount'
|
|
148
154
|
|
|
149
155
|
${clr(c.bold, 'Score meaning:')}
|
|
150
156
|
🔴 CRITICAL Sole maintainer + >10M downloads/wk (high-value attack target)
|
|
@@ -321,12 +327,14 @@ async function main() {
|
|
|
321
327
|
let filePath = null;
|
|
322
328
|
let isLockfile = false;
|
|
323
329
|
let totalInFile = 0;
|
|
330
|
+
let jsonOutput = false;
|
|
324
331
|
|
|
325
332
|
let i = 0;
|
|
326
333
|
while (i < args.length) {
|
|
327
334
|
const a = args[i];
|
|
328
335
|
if (a === '--pypi') { ecosystem = 'pypi'; i++; }
|
|
329
336
|
else if (a === '--npm') { ecosystem = 'npm'; i++; }
|
|
337
|
+
else if (a === '--json') { jsonOutput = true; i++; }
|
|
330
338
|
else if (a === '--file' || a === '-f') {
|
|
331
339
|
filePath = args[++i];
|
|
332
340
|
i++;
|
|
@@ -345,7 +353,7 @@ async function main() {
|
|
|
345
353
|
ecosystem = result.ecosystem;
|
|
346
354
|
isLockfile = result.lockfile || false;
|
|
347
355
|
totalInFile = result.totalInFile || packages.length;
|
|
348
|
-
console.log(clr(c.dim, `Detected ${totalInFile} packages from ${filePath} (${ecosystem})`));
|
|
356
|
+
if (!jsonOutput) console.log(clr(c.dim, `Detected ${totalInFile} packages from ${filePath} (${ecosystem})`));
|
|
349
357
|
} catch (err) {
|
|
350
358
|
console.error(`Error reading ${filePath}: ${err.message}`);
|
|
351
359
|
process.exit(1);
|
|
@@ -363,7 +371,7 @@ async function main() {
|
|
|
363
371
|
|
|
364
372
|
if (packages.length <= 20) {
|
|
365
373
|
// Single batch — existing behavior
|
|
366
|
-
process.stdout.write(clr(c.dim, `Scoring ${packages.length} ${ecosystem} package${packages.length > 1 ? 's' : ''}...`));
|
|
374
|
+
if (!jsonOutput) process.stdout.write(clr(c.dim, `Scoring ${packages.length} ${ecosystem} package${packages.length > 1 ? 's' : ''}...`));
|
|
367
375
|
|
|
368
376
|
try {
|
|
369
377
|
const res = await fetch(API, {
|
|
@@ -383,12 +391,12 @@ async function main() {
|
|
|
383
391
|
}
|
|
384
392
|
|
|
385
393
|
const elapsed = ((Date.now() - t0) / 1000).toFixed(1);
|
|
386
|
-
process.stdout.write(clr(c.dim, ` done in ${elapsed}s\n`));
|
|
394
|
+
if (!jsonOutput) process.stdout.write(clr(c.dim, ` done in ${elapsed}s\n`));
|
|
387
395
|
|
|
388
396
|
} else {
|
|
389
397
|
// Multi-batch for lock files
|
|
390
398
|
const batches = Math.ceil(packages.length / 20);
|
|
391
|
-
process.stdout.write(clr(c.dim, `Scanning ${packages.length} packages (${batches} batches in parallel)...`));
|
|
399
|
+
if (!jsonOutput) process.stdout.write(clr(c.dim, `Scanning ${packages.length} packages (${batches} batches in parallel)...`));
|
|
392
400
|
|
|
393
401
|
let lastPct = 0;
|
|
394
402
|
try {
|
|
@@ -407,24 +415,46 @@ async function main() {
|
|
|
407
415
|
}
|
|
408
416
|
|
|
409
417
|
const elapsed = ((Date.now() - t0) / 1000).toFixed(1);
|
|
410
|
-
process.stdout.write(clr(c.dim, ` done in ${elapsed}s\n`));
|
|
418
|
+
if (!jsonOutput) process.stdout.write(clr(c.dim, ` done in ${elapsed}s\n`));
|
|
419
|
+
|
|
420
|
+
// JSON output: emit all results with summary
|
|
421
|
+
if (jsonOutput) {
|
|
422
|
+
const criticalCount = allResults.filter(r => r.riskFlags?.includes('CRITICAL')).length;
|
|
423
|
+
console.log(JSON.stringify({
|
|
424
|
+
totalScanned: allResults.length,
|
|
425
|
+
criticalCount,
|
|
426
|
+
results: allResults,
|
|
427
|
+
}, null, 2));
|
|
428
|
+
process.exit(criticalCount > 0 ? 1 : 0);
|
|
429
|
+
}
|
|
411
430
|
|
|
412
431
|
// For lock files: show top 25 highest-risk packages
|
|
413
432
|
const MAX_DISPLAY = 25;
|
|
414
433
|
const displayed = allResults.slice(0, MAX_DISPLAY);
|
|
415
|
-
const criticalCount = allResults.filter(r => r.riskFlags?.includes('CRITICAL')).length;
|
|
416
|
-
const highRiskCount = allResults.filter(r => !r.riskFlags?.includes('CRITICAL') && r.score < 40).length;
|
|
417
|
-
|
|
418
434
|
const criticalTotal = allResults.filter(r => r.riskFlags?.includes('CRITICAL')).length;
|
|
419
435
|
printTable(displayed, { totalScanned: allResults.length, totalCritical: criticalTotal, lockfile: true });
|
|
420
436
|
return;
|
|
421
437
|
}
|
|
422
438
|
|
|
423
439
|
if (!allResults || allResults.length === 0) {
|
|
424
|
-
|
|
440
|
+
if (jsonOutput) {
|
|
441
|
+
console.log(JSON.stringify({ totalScanned: 0, criticalCount: 0, results: [] }, null, 2));
|
|
442
|
+
} else {
|
|
443
|
+
console.log('No results returned. Check package names and try again.');
|
|
444
|
+
}
|
|
425
445
|
process.exit(0);
|
|
426
446
|
}
|
|
427
447
|
|
|
448
|
+
if (jsonOutput) {
|
|
449
|
+
const criticalCount = allResults.filter(r => r.riskFlags?.includes('CRITICAL')).length;
|
|
450
|
+
console.log(JSON.stringify({
|
|
451
|
+
totalScanned: allResults.length,
|
|
452
|
+
criticalCount,
|
|
453
|
+
results: allResults,
|
|
454
|
+
}, null, 2));
|
|
455
|
+
process.exit(criticalCount > 0 ? 1 : 0);
|
|
456
|
+
}
|
|
457
|
+
|
|
428
458
|
printTable(allResults);
|
|
429
459
|
}
|
|
430
460
|
|