proof-of-commitment 1.24.0 โ 1.25.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 +69 -18
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -413,10 +413,11 @@ function printTable(results, { totalScanned, totalCritical, lockfile } = {}) {
|
|
|
413
413
|
console.log(clr(c.dim, `\n ๐ Monitor ${effectiveCritical === 1 ? 'this package' : 'these packages'}: `) +
|
|
414
414
|
clr(c.cyan, `poc watch ${results.find(r => hasCritical(r.riskFlags))?.name || results[0]?.name}`));
|
|
415
415
|
} else if (!process.stdin.isTTY || !process.stdout.isTTY) {
|
|
416
|
-
// Non-TTY (CI, piped): show
|
|
416
|
+
// Non-TTY (CI, piped): show one-step watch command since interactive prompt won't work
|
|
417
|
+
const watchPkg = results.find(r => hasCritical(r.riskFlags))?.name || results[0]?.name;
|
|
417
418
|
console.log(clr(c.dim, `\n ๐ Monitor ${effectiveCritical === 1 ? 'this' : 'these ' + effectiveCritical} CRITICAL ${effectiveCritical === 1 ? 'package' : 'packages'} โ get alerted when scores change.`));
|
|
418
|
-
console.log(clr(c.dim, '
|
|
419
|
-
console.log(clr(c.dim, '
|
|
419
|
+
console.log(clr(c.dim, ' One step: ') + clr(c.cyan, `poc watch ${watchPkg} --email you@company.com`));
|
|
420
|
+
console.log(clr(c.dim, ' Free: 3 packages, weekly digest. Developer $15/mo: 15 packages, daily scans.'));
|
|
420
421
|
}
|
|
421
422
|
// else: TTY mode โ inlineSignup() will prompt interactively after printTable
|
|
422
423
|
} else if (!hasKey && (!process.stdin.isTTY || !process.stdout.isTTY)) {
|
|
@@ -426,8 +427,8 @@ function printTable(results, { totalScanned, totalCritical, lockfile } = {}) {
|
|
|
426
427
|
// text only in CI/piped output where interactive prompts can't fire.
|
|
427
428
|
// ref=audit-baseline distinguishes this funnel from audit-cli-429
|
|
428
429
|
// (rate-limit rescue) and from the static utm_source=cli help-line.
|
|
429
|
-
console.log(clr(c.dim, '\n ๐
|
|
430
|
-
console.log(clr(c.dim, ' ') + clr(c.cyan, '
|
|
430
|
+
console.log(clr(c.dim, '\n ๐ Get alerted if any package degrades:'));
|
|
431
|
+
console.log(clr(c.dim, ' ') + clr(c.cyan, `poc watch ${results[0]?.name || '<package>'} --email you@company.com`) + clr(c.dim, ' (free: 3 packages, weekly digest)'));
|
|
431
432
|
}
|
|
432
433
|
console.log();
|
|
433
434
|
}
|
|
@@ -505,15 +506,15 @@ async function inlineSignup(results) {
|
|
|
505
506
|
console.log(clr(c.dim, ` Backup sent to ${email}`));
|
|
506
507
|
console.log();
|
|
507
508
|
console.log(clr(c.bold, ' Next steps:'));
|
|
508
|
-
console.log(clr(c.dim, ' โข ') + clr(c.cyan, 'poc status') + clr(c.dim, ' โ check your account'));
|
|
509
509
|
// Surface a concrete watch target. CRITICAL first (highest urgency);
|
|
510
510
|
// otherwise pick the lowest-score package as the most-likely-to-degrade.
|
|
511
511
|
const watchTarget = critPkgs[0]?.name
|
|
512
512
|
|| results.slice().sort((a, b) => (a.score || 100) - (b.score || 100))[0]?.name;
|
|
513
513
|
if (watchTarget) {
|
|
514
|
-
console.log(clr(c.dim, ' โข ') + clr(c.cyan, `poc watch ${watchTarget}`) + clr(c.dim, ' โ
|
|
514
|
+
console.log(clr(c.dim, ' โข ') + clr(c.cyan, `poc watch ${watchTarget}`) + clr(c.dim, ' โ monitor this package (free: 3 packages, weekly)'));
|
|
515
515
|
}
|
|
516
516
|
console.log(clr(c.dim, ' โข ') + clr(c.cyan, 'poc init') + clr(c.dim, ' โ add CI gate to this project'));
|
|
517
|
+
console.log(clr(c.dim, ' โข ') + clr(c.cyan, 'poc status') + clr(c.dim, ' โ check your account'));
|
|
517
518
|
} else if (data.message) {
|
|
518
519
|
console.log(clr(c.green, ` โ ${data.message}`));
|
|
519
520
|
} else {
|
|
@@ -566,9 +567,9 @@ ${clr(c.bold, 'Account:')}
|
|
|
566
567
|
poc status Show current tier, usage, and limits
|
|
567
568
|
poc logout Remove saved API key
|
|
568
569
|
|
|
569
|
-
${clr(c.bold, 'Monitoring (Developer $15/mo
|
|
570
|
-
poc watch <package> [--ecosystem npm|pypi|cargo|golang]
|
|
571
|
-
Add a package to
|
|
570
|
+
${clr(c.bold, 'Monitoring (free: 3 packages weekly ยท Developer $15/mo: 15 daily):')}
|
|
571
|
+
poc watch <package> [--email you@co.com] [--ecosystem npm|pypi|cargo|golang]
|
|
572
|
+
Add a package to monitoring. --email creates a free key in one step.
|
|
572
573
|
poc watchlist List monitored packages with current scores + risk
|
|
573
574
|
poc unwatch <pkg> Remove a package from monitoring
|
|
574
575
|
|
|
@@ -1555,15 +1556,53 @@ async function printUpgradeRequired(res, campaign = 'watchlist-402') {
|
|
|
1555
1556
|
/**
|
|
1556
1557
|
* poc watch <package> [--ecosystem npm|pypi|cargo|golang]
|
|
1557
1558
|
*/
|
|
1558
|
-
async function cmdWatch(pkg, ecosystem) {
|
|
1559
|
-
|
|
1559
|
+
async function cmdWatch(pkg, ecosystem, emailArg) {
|
|
1560
|
+
let key = await readApiKey();
|
|
1561
|
+
|
|
1562
|
+
// --email flag: create a free key inline if none exists, collapsing the
|
|
1563
|
+
// visit-site โ enter-email โ copy-key โ poc-login โ poc-watch flow to one step.
|
|
1564
|
+
if (!key && emailArg) {
|
|
1565
|
+
if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(emailArg)) {
|
|
1566
|
+
console.error(clr(c.red, 'Invalid email. Usage: poc watch <pkg> --email you@co.com'));
|
|
1567
|
+
process.exit(1);
|
|
1568
|
+
}
|
|
1569
|
+
process.stdout.write(clr(c.dim, ' Creating free API key...'));
|
|
1570
|
+
try {
|
|
1571
|
+
const createRes = await fetch('https://poc-backend.amdal-dev.workers.dev/api/keys/create', {
|
|
1572
|
+
method: 'POST',
|
|
1573
|
+
headers: { 'Content-Type': 'application/json' },
|
|
1574
|
+
body: JSON.stringify({ email: emailArg, source: 'cli-watch' }),
|
|
1575
|
+
});
|
|
1576
|
+
const keyData = await createRes.json();
|
|
1577
|
+
if (keyData.key) {
|
|
1578
|
+
await writeApiKey(keyData.key);
|
|
1579
|
+
key = keyData.key;
|
|
1580
|
+
console.log(clr(c.green, ' โ'));
|
|
1581
|
+
console.log(clr(c.dim, ` Key saved to ~/.commit/config. Backup sent to ${emailArg}.`));
|
|
1582
|
+
} else {
|
|
1583
|
+
const errMsg = keyData.error === 'rate_limit_exceeded'
|
|
1584
|
+
? 'Too many keys from this IP today.'
|
|
1585
|
+
: (keyData.message || 'Could not create key.');
|
|
1586
|
+
console.error(clr(c.red, ` ${errMsg}`));
|
|
1587
|
+
process.exit(1);
|
|
1588
|
+
}
|
|
1589
|
+
} catch (err) {
|
|
1590
|
+
console.error(clr(c.red, ` Error: ${err.message}`));
|
|
1591
|
+
process.exit(1);
|
|
1592
|
+
}
|
|
1593
|
+
}
|
|
1594
|
+
|
|
1560
1595
|
if (!key) {
|
|
1561
|
-
console.error(clr(c.red, 'No API key found.
|
|
1562
|
-
console.error(
|
|
1596
|
+
console.error(clr(c.red, 'No API key found.'));
|
|
1597
|
+
console.error('');
|
|
1598
|
+
console.error(clr(c.bold, ' One-step setup โ creates key + starts monitoring:'));
|
|
1599
|
+
console.error(clr(c.cyan, ` poc watch ${pkg} --email you@company.com`));
|
|
1600
|
+
console.error('');
|
|
1601
|
+
console.error(clr(c.dim, ' Or set COMMIT_API_KEY / add api_key=<key> to ~/.commit/config'));
|
|
1563
1602
|
process.exit(1);
|
|
1564
1603
|
}
|
|
1565
1604
|
|
|
1566
|
-
process.stdout.write(clr(c.dim, `Adding ${pkg} (${ecosystem}) to watchlist...`));
|
|
1605
|
+
process.stdout.write(clr(c.dim, ` Adding ${pkg} (${ecosystem}) to watchlist...`));
|
|
1567
1606
|
const res = await fetch(WATCHLIST_API, {
|
|
1568
1607
|
method: 'POST',
|
|
1569
1608
|
headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${key}` },
|
|
@@ -1571,6 +1610,16 @@ async function cmdWatch(pkg, ecosystem) {
|
|
|
1571
1610
|
});
|
|
1572
1611
|
|
|
1573
1612
|
if (res.status === 402) { process.stdout.write('\n'); await printUpgradeRequired(res, 'watch-cmd'); process.exit(1); }
|
|
1613
|
+
if (res.status === 422) {
|
|
1614
|
+
const errData = await res.json().catch(() => ({}));
|
|
1615
|
+
process.stdout.write('\n');
|
|
1616
|
+
console.log(clr(c.yellow, ` โ ${errData.message || 'Package limit reached.'}`));
|
|
1617
|
+
if (errData.upgrade) {
|
|
1618
|
+
console.log(clr(c.dim, ` ${errData.upgrade.message || `Upgrade to ${errData.upgrade.plan} for more:`}`));
|
|
1619
|
+
console.log(clr(c.cyan, ` ${errData.upgrade.url}`));
|
|
1620
|
+
}
|
|
1621
|
+
process.exit(1);
|
|
1622
|
+
}
|
|
1574
1623
|
|
|
1575
1624
|
const data = await res.json();
|
|
1576
1625
|
if (!res.ok) {
|
|
@@ -1582,7 +1631,7 @@ async function cmdWatch(pkg, ecosystem) {
|
|
|
1582
1631
|
process.stdout.write('\n');
|
|
1583
1632
|
if (isNew) {
|
|
1584
1633
|
console.log(clr(c.green, ` โ Now watching ${pkg}`));
|
|
1585
|
-
console.log(clr(c.dim, '
|
|
1634
|
+
console.log(clr(c.dim, ' Weekly digest (Mondays). Upgrade to Developer ($15/mo) for daily scans + Slack alerts.'));
|
|
1586
1635
|
} else {
|
|
1587
1636
|
console.log(clr(c.dim, ` โฉ ${pkg} is already in your watchlist`));
|
|
1588
1637
|
}
|
|
@@ -2177,15 +2226,17 @@ async function main() {
|
|
|
2177
2226
|
|
|
2178
2227
|
if (subcmd === 'watch') {
|
|
2179
2228
|
const pkg = args[1];
|
|
2180
|
-
if (!pkg) { console.error('Usage: poc watch <package> [--ecosystem npm|pypi|cargo|golang]'); process.exit(1); }
|
|
2229
|
+
if (!pkg) { console.error('Usage: poc watch <package> [--email you@co.com] [--ecosystem npm|pypi|cargo|golang]'); process.exit(1); }
|
|
2181
2230
|
let ecosystem = 'npm';
|
|
2231
|
+
let email = null;
|
|
2182
2232
|
for (let i = 2; i < args.length; i++) {
|
|
2183
2233
|
if (args[i] === '--ecosystem' || args[i] === '-e') ecosystem = args[++i] || 'npm';
|
|
2234
|
+
else if (args[i] === '--email') email = args[++i] || null;
|
|
2184
2235
|
else if (args[i] === '--pypi') ecosystem = 'pypi';
|
|
2185
2236
|
else if (args[i] === '--cargo') ecosystem = 'cargo';
|
|
2186
2237
|
else if (args[i] === '--golang' || args[i] === '--go') ecosystem = 'golang';
|
|
2187
2238
|
}
|
|
2188
|
-
await cmdWatch(pkg, ecosystem);
|
|
2239
|
+
await cmdWatch(pkg, ecosystem, email);
|
|
2189
2240
|
process.exit(0);
|
|
2190
2241
|
}
|
|
2191
2242
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "proof-of-commitment",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.25.0",
|
|
4
4
|
"mcpName": "io.github.piiiico/proof-of-commitment",
|
|
5
5
|
"description": "Supply chain security risk scorer for npm, PyPI, Cargo, and Go packages โ behavioral signals that can't be faked",
|
|
6
6
|
"type": "module",
|