proof-of-commitment 1.18.1 → 1.19.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/README.md +14 -17
- package/index.js +67 -38
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -51,26 +51,23 @@ npx proof-of-commitment --file go.sum # full transitive set
|
|
|
51
51
|
|
|
52
52
|
**Web demo (no install):** [getcommit.dev/audit](https://getcommit.dev/audit) — paste your packages, see risk scores in seconds.
|
|
53
53
|
|
|
54
|
-
|
|
54
|
+
## Get notified before the next attack
|
|
55
|
+
|
|
56
|
+
The CLI tells you what's risky today. A free API key unlocks **monitoring** — daily score recomputation across the packages you depend on, with alerts when one degrades (publisher drops, release stalls, score falls ≥10 points).
|
|
57
|
+
|
|
58
|
+
[**Get a free API key →**](https://getcommit.dev/get-started?ref=npm-readme-monitoring&utm_source=cli) — no card, 30 seconds · 200 audits/day free · Developer $15/mo unlocks alerts + watchlist.
|
|
59
|
+
|
|
55
60
|
```bash
|
|
56
61
|
# Install once, then use the `poc` alias:
|
|
57
62
|
npm install -g proof-of-commitment
|
|
58
63
|
|
|
59
|
-
#
|
|
60
|
-
poc login sk_commit_your_key_here
|
|
61
|
-
#
|
|
62
|
-
|
|
63
|
-
poc status # check tier + usage anytime
|
|
64
|
-
poc logout # remove saved key
|
|
65
|
-
|
|
66
|
-
# Monitoring (Pro tier — daily scans + alerts):
|
|
67
|
-
poc watch chalk
|
|
64
|
+
# After getting your free key:
|
|
65
|
+
poc login sk_commit_your_key_here # save and validate
|
|
66
|
+
poc status # check tier + usage
|
|
67
|
+
poc watch chalk # start monitoring (Developer $15/mo)
|
|
68
68
|
poc watch requests --ecosystem pypi
|
|
69
|
-
poc
|
|
70
|
-
poc
|
|
71
|
-
poc unwatch chalk
|
|
72
|
-
|
|
73
|
-
# Upgrade to Pro: https://getcommit.dev/pricing
|
|
69
|
+
poc watchlist # view all watched packages
|
|
70
|
+
poc init # add CI gate to this project
|
|
74
71
|
```
|
|
75
72
|
|
|
76
73
|
Alerts fire on: score drop ≥10 points · package crosses CRITICAL threshold · recovery to HEALTHY.
|
|
@@ -132,12 +129,12 @@ When `comment-on-pr: true` (default), the action automatically posts the audit t
|
|
|
132
129
|
| `max-packages` | `20` | Max packages to audit when auto-detecting |
|
|
133
130
|
| `include-dev-dependencies` | `false` | Include `devDependencies` from `package.json` |
|
|
134
131
|
| `comment-on-pr` | `true` | Post audit results as a PR comment (requires `pull-requests: write` permission) |
|
|
135
|
-
| `api-key` | _(none)_ | [Commit
|
|
132
|
+
| `api-key` | _(none)_ | [Commit](https://getcommit.dev/pricing) API key — enables batch requests; Developer ($15/mo) gets 10K requests/month |
|
|
136
133
|
| `api-url` | _(prod)_ | Override API endpoint (useful for self-hosting) |
|
|
137
134
|
|
|
138
135
|
**Outputs:** `has-critical`, `critical-count`, `audit-summary` (markdown table, also written to Step Summary).
|
|
139
136
|
|
|
140
|
-
**Free vs
|
|
137
|
+
**Free vs paid:** Without an API key, packages are audited one at a time (with delays to respect rate limits). With any API key (free or paid), all packages are audited in a single batch request — faster. Paid tiers (Developer $15/mo+) raise the monthly request limit and unlock daily monitoring.
|
|
141
138
|
|
|
142
139
|
Example PR comment / Step Summary output:
|
|
143
140
|
|
package/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
|
-
* proof-of-commitment CLI v1.
|
|
3
|
+
* proof-of-commitment CLI v1.19.0
|
|
4
4
|
* Scores npm/PyPI/Cargo/Go packages on behavioral commitment signals.
|
|
5
5
|
* Usage: npx proof-of-commitment [packages...] [options]
|
|
6
6
|
*/
|
|
@@ -293,15 +293,11 @@ function printTable(results, { totalScanned, totalCritical, lockfile } = {}) {
|
|
|
293
293
|
console.log(clr(c.dim, ' Then run: ') + clr(c.cyan, 'poc login'));
|
|
294
294
|
}
|
|
295
295
|
// else: TTY mode — inlineSignup() will prompt interactively after printTable
|
|
296
|
-
} else if (!hasKey) {
|
|
297
|
-
// HEALTHY case + no saved key:
|
|
298
|
-
//
|
|
299
|
-
//
|
|
300
|
-
//
|
|
301
|
-
// hidden behind the CRITICAL gate of inlineSignup(). Buyer-journey
|
|
302
|
-
// dogfood 2026-05-24 found 1472 weekly downloads → 0 organic signups;
|
|
303
|
-
// the watchlist value prop ("alert me when these degrade") is real
|
|
304
|
-
// for healthy packages too — that's exactly when monitoring matters.
|
|
296
|
+
} else if (!hasKey && (!process.stdin.isTTY || !process.stdout.isTTY)) {
|
|
297
|
+
// HEALTHY case + no saved key + non-TTY (CI/piped): static baseline CTA.
|
|
298
|
+
// In TTY mode, inlineSignup() now prompts interactively for healthy results
|
|
299
|
+
// too — the dim text below converted 0/621 weekly downloads. Keep static
|
|
300
|
+
// text only in CI/piped output where interactive prompts can't fire.
|
|
305
301
|
// ref=audit-baseline distinguishes this funnel from audit-cli-429
|
|
306
302
|
// (rate-limit rescue) and from the static utm_source=cli help-line.
|
|
307
303
|
console.log(clr(c.dim, '\n 📊 Save this scan as your baseline. Re-run anytime with a free key:'));
|
|
@@ -311,23 +307,35 @@ function printTable(results, { totalScanned, totalCritical, lockfile } = {}) {
|
|
|
311
307
|
}
|
|
312
308
|
|
|
313
309
|
/**
|
|
314
|
-
* Inline signup: after
|
|
310
|
+
* Inline signup: after any real audit, offer one-step email→key flow.
|
|
315
311
|
* Collapses 6-step funnel (visit site → email → check inbox → copy key → login → watch)
|
|
316
312
|
* into a single CLI prompt.
|
|
313
|
+
*
|
|
314
|
+
* v1.19: Triggers on healthy results too (≥3 packages). The dim "Save this scan
|
|
315
|
+
* as your baseline" footer line converted 0/621 weekly downloads — replacing it
|
|
316
|
+
* with an interactive prompt at the moment of audit success captures more
|
|
317
|
+
* intent. Copy adapts to context: degradation alerts (CRITICAL) vs baseline
|
|
318
|
+
* lock-in (healthy). Quick lookups (<3 packages) still skip the prompt.
|
|
317
319
|
*/
|
|
318
320
|
async function inlineSignup(results) {
|
|
319
|
-
// Only prompt in interactive TTY when
|
|
321
|
+
// Only prompt in interactive TTY when no key saved
|
|
320
322
|
if (!process.stdin.isTTY || !process.stdout.isTTY) return;
|
|
321
323
|
const hasKey = !!process.env.COMMIT_API_KEY || _cachedHasKey;
|
|
322
324
|
if (hasKey) return;
|
|
323
325
|
const critPkgs = results.filter(r => hasCritical(r.riskFlags));
|
|
324
326
|
const lowScorePkgs = results.filter(r => typeof r.score === 'number' && r.score < 60);
|
|
325
|
-
// Gate: ≥
|
|
326
|
-
|
|
327
|
-
|
|
327
|
+
// Gate: ≥3 packages scanned (real audit, not a one-off `npx poc somepkg` check)
|
|
328
|
+
if (results.length < 3) return;
|
|
329
|
+
|
|
330
|
+
const hasFindings = critPkgs.length >= 1 || lowScorePkgs.length >= 2;
|
|
331
|
+
// Copy adapts to context. Findings → degradation framing.
|
|
332
|
+
// Healthy → baseline-lock framing (still real value: alert me if any score drops).
|
|
333
|
+
const heading = hasFindings
|
|
334
|
+
? ' 🔔 Lock in this audit. Get alerted if these packages get worse.'
|
|
335
|
+
: ' 🔔 Lock in this baseline. Get alerted if any of these packages degrade.';
|
|
328
336
|
|
|
329
337
|
console.log(clr(c.dim, ' ─────────────────────────────────────────────'));
|
|
330
|
-
console.log(clr(c.bold,
|
|
338
|
+
console.log(clr(c.bold, heading));
|
|
331
339
|
console.log(clr(c.dim, ' Free, no card, 10 seconds. Saves to ~/.commit/config.\n'));
|
|
332
340
|
|
|
333
341
|
const { createInterface } = await import('readline');
|
|
@@ -366,8 +374,12 @@ async function inlineSignup(results) {
|
|
|
366
374
|
console.log();
|
|
367
375
|
console.log(clr(c.bold, ' Next steps:'));
|
|
368
376
|
console.log(clr(c.dim, ' • ') + clr(c.cyan, 'poc status') + clr(c.dim, ' — check your account'));
|
|
369
|
-
|
|
370
|
-
|
|
377
|
+
// Surface a concrete watch target. CRITICAL first (highest urgency);
|
|
378
|
+
// otherwise pick the lowest-score package as the most-likely-to-degrade.
|
|
379
|
+
const watchTarget = critPkgs[0]?.name
|
|
380
|
+
|| results.slice().sort((a, b) => (a.score || 100) - (b.score || 100))[0]?.name;
|
|
381
|
+
if (watchTarget) {
|
|
382
|
+
console.log(clr(c.dim, ' • ') + clr(c.cyan, `poc watch ${watchTarget}`) + clr(c.dim, ' — start monitoring (Developer $15/mo)'));
|
|
371
383
|
}
|
|
372
384
|
console.log(clr(c.dim, ' • ') + clr(c.cyan, 'poc init') + clr(c.dim, ' — add CI gate to this project'));
|
|
373
385
|
} else if (data.message) {
|
|
@@ -384,7 +396,7 @@ async function inlineSignup(results) {
|
|
|
384
396
|
|
|
385
397
|
function printHelp() {
|
|
386
398
|
console.log(`
|
|
387
|
-
${clr(c.bold, 'proof-of-commitment')} v1.
|
|
399
|
+
${clr(c.bold, 'proof-of-commitment')} v1.19.0 — supply chain risk scorer
|
|
388
400
|
|
|
389
401
|
${clr(c.bold, 'Usage:')}
|
|
390
402
|
npx proof-of-commitment Auto-detect manifest in current dir
|
|
@@ -415,14 +427,14 @@ ${clr(c.bold, 'Account:')}
|
|
|
415
427
|
poc status Show current tier, usage, and limits
|
|
416
428
|
poc logout Remove saved API key
|
|
417
429
|
|
|
418
|
-
${clr(c.bold, 'Monitoring (
|
|
430
|
+
${clr(c.bold, 'Monitoring (Developer $15/mo+):')}
|
|
419
431
|
poc watch <package> [--ecosystem npm|pypi|cargo|golang]
|
|
420
432
|
Add a package to daily monitoring
|
|
421
433
|
poc watchlist List monitored packages with current scores + risk
|
|
422
434
|
poc unwatch <pkg> Remove a package from monitoring
|
|
423
435
|
|
|
424
|
-
Get a free key:
|
|
425
|
-
|
|
436
|
+
Get a free key: https://getcommit.dev/get-started?utm_source=cli
|
|
437
|
+
Enable monitoring: https://getcommit.dev/pricing?utm_source=cli&utm_campaign=help
|
|
426
438
|
|
|
427
439
|
${clr(c.bold, 'Options:')}
|
|
428
440
|
--json Output results as JSON
|
|
@@ -965,13 +977,14 @@ async function cmdLogin(keyArg) {
|
|
|
965
977
|
console.log(clr(c.dim, ` Saved to: ${configPath}`));
|
|
966
978
|
console.log();
|
|
967
979
|
|
|
968
|
-
if (info.tier === 'pro' || info.tier === 'enterprise') {
|
|
969
|
-
console.log(clr(c.cyan, '
|
|
980
|
+
if (info.tier === 'developer' || info.tier === 'pro' || info.tier === 'enterprise') {
|
|
981
|
+
console.log(clr(c.cyan, ' Monitoring unlocked:'));
|
|
970
982
|
console.log(clr(c.dim, ' poc watch <package> Add a package to daily monitoring'));
|
|
971
983
|
console.log(clr(c.dim, ' poc watchlist View monitored packages'));
|
|
972
984
|
console.log(clr(c.dim, ' poc unwatch <package> Remove from monitoring'));
|
|
973
985
|
} else {
|
|
974
|
-
console.log(clr(c.dim, '
|
|
986
|
+
console.log(clr(c.dim, ' Enable monitoring + alerts on Developer ($15/mo):'));
|
|
987
|
+
console.log(clr(c.cyan, ' https://getcommit.dev/pricing?utm_source=cli&utm_campaign=post-login'));
|
|
975
988
|
}
|
|
976
989
|
console.log();
|
|
977
990
|
}
|
|
@@ -1009,7 +1022,8 @@ async function cmdStatus() {
|
|
|
1009
1022
|
if (info.tier === 'free') {
|
|
1010
1023
|
const pct = info.requests_limit > 0 ? Math.round((info.requests_used / info.requests_limit) * 100) : 0;
|
|
1011
1024
|
if (pct >= 80) {
|
|
1012
|
-
console.log(clr(c.yellow, ` ⚠ ${pct}% of daily limit used.
|
|
1025
|
+
console.log(clr(c.yellow, ` ⚠ ${pct}% of daily limit used. Developer ($15/mo) gets 10K/month + monitoring:`));
|
|
1026
|
+
console.log(clr(c.cyan, ` https://getcommit.dev/pricing?utm_source=cli&utm_campaign=status-limit`));
|
|
1013
1027
|
}
|
|
1014
1028
|
}
|
|
1015
1029
|
}
|
|
@@ -1036,11 +1050,24 @@ function tierLabel(tier) {
|
|
|
1036
1050
|
|
|
1037
1051
|
/**
|
|
1038
1052
|
* Handle 402 upgrade response from watchlist endpoints.
|
|
1053
|
+
* Reads server response so the tier name, price, and URL stay authoritative
|
|
1054
|
+
* (server is canonical — CLI was historically out of date saying "Pro" when
|
|
1055
|
+
* "Developer" was the actual gate). Appends CLI UTM for attribution.
|
|
1039
1056
|
*/
|
|
1040
|
-
function printUpgradeRequired() {
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1057
|
+
async function printUpgradeRequired(res, campaign = 'watchlist-402') {
|
|
1058
|
+
let body = null;
|
|
1059
|
+
try { body = await res.json(); } catch {}
|
|
1060
|
+
const plan = (body && body.upgrade && body.upgrade.plan) || 'developer';
|
|
1061
|
+
const planLabel = plan.charAt(0).toUpperCase() + plan.slice(1);
|
|
1062
|
+
const price = (body && body.upgrade && body.upgrade.price) || '$15/month';
|
|
1063
|
+
const baseUrl = (body && body.upgrade && body.upgrade.url) || 'https://getcommit.dev/pricing';
|
|
1064
|
+
const url = baseUrl + (baseUrl.includes('?') ? '&' : '?') + `utm_source=cli&utm_campaign=${campaign}`;
|
|
1065
|
+
const currentTier = body && body.current_tier ? body.current_tier : 'free';
|
|
1066
|
+
|
|
1067
|
+
console.error(clr(c.yellow + c.bold, `\n ✦ ${planLabel} (${price}) required`));
|
|
1068
|
+
console.error(clr(c.dim, ` Monitoring, daily scans, and alerts start on ${planLabel}.`));
|
|
1069
|
+
console.error(clr(c.dim, ` Current tier: ${currentTier}`));
|
|
1070
|
+
console.error(clr(c.cyan, ` Upgrade at ${url}\n`));
|
|
1044
1071
|
}
|
|
1045
1072
|
|
|
1046
1073
|
/**
|
|
@@ -1061,7 +1088,7 @@ async function cmdWatch(pkg, ecosystem) {
|
|
|
1061
1088
|
body: JSON.stringify({ package: pkg, ecosystem }),
|
|
1062
1089
|
});
|
|
1063
1090
|
|
|
1064
|
-
if (res.status === 402) { printUpgradeRequired(); process.exit(1); }
|
|
1091
|
+
if (res.status === 402) { process.stdout.write('\n'); await printUpgradeRequired(res, 'watch-cmd'); process.exit(1); }
|
|
1065
1092
|
|
|
1066
1093
|
const data = await res.json();
|
|
1067
1094
|
if (!res.ok) {
|
|
@@ -1093,7 +1120,7 @@ async function cmdWatchlist() {
|
|
|
1093
1120
|
headers: { 'Authorization': `Bearer ${key}` },
|
|
1094
1121
|
});
|
|
1095
1122
|
|
|
1096
|
-
if (res.status === 402) { printUpgradeRequired(); process.exit(1); }
|
|
1123
|
+
if (res.status === 402) { await printUpgradeRequired(res, 'watchlist-cmd'); process.exit(1); }
|
|
1097
1124
|
|
|
1098
1125
|
const data = await res.json();
|
|
1099
1126
|
if (!res.ok) {
|
|
@@ -1132,7 +1159,7 @@ async function cmdWatchlist() {
|
|
|
1132
1159
|
const divider = '─'.repeat(divWidth);
|
|
1133
1160
|
|
|
1134
1161
|
console.log('\n' + divider);
|
|
1135
|
-
console.log(clr(c.dim, ` Commit
|
|
1162
|
+
console.log(clr(c.dim, ` Commit watchlist · ${pkgs.length}/${data.limit} packages · tier: ${data.tier}`));
|
|
1136
1163
|
console.log(divider);
|
|
1137
1164
|
console.log(header);
|
|
1138
1165
|
console.log(divider);
|
|
@@ -1175,7 +1202,7 @@ async function cmdUnwatch(pkg, ecosystem) {
|
|
|
1175
1202
|
body: JSON.stringify({ package: pkg, ecosystem }),
|
|
1176
1203
|
});
|
|
1177
1204
|
|
|
1178
|
-
if (res.status === 402) { printUpgradeRequired(); process.exit(1); }
|
|
1205
|
+
if (res.status === 402) { process.stdout.write('\n'); await printUpgradeRequired(res, 'unwatch-cmd'); process.exit(1); }
|
|
1179
1206
|
|
|
1180
1207
|
const data = await res.json();
|
|
1181
1208
|
if (!res.ok) {
|
|
@@ -1315,7 +1342,7 @@ ${rows}
|
|
|
1315
1342
|
<div class="footer">
|
|
1316
1343
|
<span>Generated by <a href="${WEB}" target="_blank">proof-of-commitment</a></span>
|
|
1317
1344
|
<span><a href="https://github.com/piiiico/commit-action" target="_blank">GitHub Action</a></span>
|
|
1318
|
-
<span><a href="https://getcommit.dev/pricing?utm_source=cli&utm_medium=report" target="_blank">
|
|
1345
|
+
<span><a href="https://getcommit.dev/pricing?utm_source=cli&utm_medium=report" target="_blank">Enable monitoring</a></span>
|
|
1319
1346
|
</div>
|
|
1320
1347
|
<script>
|
|
1321
1348
|
function copyMd() {
|
|
@@ -1573,9 +1600,11 @@ jobs:
|
|
|
1573
1600
|
console.log(clr(c.white, ' 1. The badge updates daily with your project\'s score'));
|
|
1574
1601
|
console.log(clr(c.white, ' 2. Push to trigger the existing workflow'));
|
|
1575
1602
|
}
|
|
1576
|
-
console.log(clr(c.dim, `\n Want daily monitoring + alerts
|
|
1577
|
-
console.log(clr(c.cyan, '
|
|
1578
|
-
console.log(clr(c.dim, '
|
|
1603
|
+
console.log(clr(c.dim, `\n Want daily monitoring + alerts on your dependencies?`));
|
|
1604
|
+
console.log(clr(c.dim, ' 1. Free key (200 scans/day): ') + clr(c.cyan, 'https://getcommit.dev/get-started?utm_source=cli'));
|
|
1605
|
+
console.log(clr(c.dim, ' 2. Authenticate: ') + clr(c.cyan, 'poc login'));
|
|
1606
|
+
console.log(clr(c.dim, ' 3. Enable monitoring ($15/mo): ') + clr(c.cyan, 'https://getcommit.dev/pricing?utm_source=cli&utm_campaign=init'));
|
|
1607
|
+
console.log(clr(c.dim, ' 4. Watch a package: ') + clr(c.cyan, 'poc watch <package>\n'));
|
|
1579
1608
|
}
|
|
1580
1609
|
|
|
1581
1610
|
async function main() {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "proof-of-commitment",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.19.0",
|
|
4
4
|
"mcpName": "io.github.piiiico/proof-of-commitment",
|
|
5
5
|
"description": "Supply chain risk scorer for npm, PyPI, Cargo, and Go packages — behavioral signals that can't be faked",
|
|
6
6
|
"type": "module",
|