proof-of-commitment 1.12.0 → 1.13.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 +92 -8
- package/package.json +1 -1
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.13.0
|
|
4
4
|
* Scores npm/PyPI/Cargo/Go packages on behavioral commitment signals.
|
|
5
5
|
* Usage: npx proof-of-commitment [packages...] [options]
|
|
6
6
|
*/
|
|
@@ -180,10 +180,23 @@ function printTable(results, { totalScanned, totalCritical, lockfile } = {}) {
|
|
|
180
180
|
|
|
181
181
|
// Footer with web link + CI integration CTA
|
|
182
182
|
const topPkgs = results.slice(0, 10).map(r => r.name).join(',');
|
|
183
|
-
|
|
183
|
+
const utm = 'utm_source=cli&utm_medium=audit';
|
|
184
|
+
console.log(clr(c.cyan, `\n 🔗 Full report: ${WEB}?packages=${encodeURIComponent(topPkgs)}&${utm}`));
|
|
184
185
|
console.log(clr(c.cyan, ` 🤖 GitHub Action: github.com/piiiico/commit-action — block CRITICAL packages in CI`));
|
|
185
186
|
console.log(clr(c.dim, ` 📋 Add to this project: `) + clr(c.cyan, `poc init`) + clr(c.dim, ` — creates workflow + README badge`));
|
|
186
187
|
|
|
188
|
+
// Per-package profile URLs — drive traffic to permanent, indexable pages
|
|
189
|
+
const ecoPath = { npm: 'npm', pypi: 'pypi', cargo: 'cargo', golang: 'go' };
|
|
190
|
+
const profilePkgs = results.slice(0, 5).filter(r => r.name && ecoPath[r.ecosystem || 'npm']);
|
|
191
|
+
if (profilePkgs.length > 0) {
|
|
192
|
+
console.log(clr(c.dim, `\n 📄 Package profiles:`));
|
|
193
|
+
for (const r of profilePkgs) {
|
|
194
|
+
const eco = ecoPath[r.ecosystem || 'npm'];
|
|
195
|
+
const name = encodeURIComponent(r.name).replace(/%40/g, '@').replace(/%2F/g, '/');
|
|
196
|
+
console.log(clr(c.dim, ` getcommit.dev/${eco}/${name}`));
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
187
200
|
// Contextual upsell — show when findings make monitoring relevant
|
|
188
201
|
if (effectiveCritical > 0) {
|
|
189
202
|
// Check for API key synchronously via env (fast path)
|
|
@@ -193,16 +206,85 @@ function printTable(results, { totalScanned, totalCritical, lockfile } = {}) {
|
|
|
193
206
|
clr(c.cyan, `poc watch ${results.find(r => hasCritical(r.riskFlags))?.name || results[0]?.name}`));
|
|
194
207
|
} else {
|
|
195
208
|
console.log(clr(c.dim, `\n 📊 Monitor ${effectiveCritical === 1 ? 'this' : 'these ' + effectiveCritical} CRITICAL ${effectiveCritical === 1 ? 'package' : 'packages'} — get alerted when scores change.`));
|
|
196
|
-
console.log(clr(c.dim, ' Get a free API key: ') + clr(c.cyan, 'https://getcommit.dev/get-started'));
|
|
209
|
+
console.log(clr(c.dim, ' Get a free API key: ') + clr(c.cyan, 'https://getcommit.dev/get-started?utm_source=cli'));
|
|
197
210
|
console.log(clr(c.dim, ' Then run: ') + clr(c.cyan, 'poc login'));
|
|
198
211
|
}
|
|
199
212
|
}
|
|
200
213
|
console.log();
|
|
201
214
|
}
|
|
202
215
|
|
|
216
|
+
/**
|
|
217
|
+
* Inline signup: after CRITICAL findings, offer one-step email→key flow.
|
|
218
|
+
* Collapses 6-step funnel (visit site → email → check inbox → copy key → login → watch)
|
|
219
|
+
* into a single CLI prompt.
|
|
220
|
+
*/
|
|
221
|
+
async function inlineSignup(results) {
|
|
222
|
+
// Only prompt in interactive TTY when CRITICAL packages found and no key saved
|
|
223
|
+
if (!process.stdin.isTTY || !process.stdout.isTTY) return;
|
|
224
|
+
const hasKey = !!process.env.COMMIT_API_KEY || _cachedHasKey;
|
|
225
|
+
if (hasKey) return;
|
|
226
|
+
const critPkgs = results.filter(r => hasCritical(r.riskFlags));
|
|
227
|
+
if (critPkgs.length === 0) return;
|
|
228
|
+
|
|
229
|
+
console.log(clr(c.dim, ' ─────────────────────────────────────────────'));
|
|
230
|
+
console.log(clr(c.bold, ' 🔔 Get alerts when these scores change?'));
|
|
231
|
+
console.log(clr(c.dim, ' Free API key — no credit card, 10 seconds.\n'));
|
|
232
|
+
|
|
233
|
+
const { createInterface } = await import('readline');
|
|
234
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
235
|
+
|
|
236
|
+
const email = await new Promise(resolve => {
|
|
237
|
+
rl.question(clr(c.dim, ' Your email (Enter to skip): '), answer => {
|
|
238
|
+
rl.close();
|
|
239
|
+
resolve(answer.trim());
|
|
240
|
+
});
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
if (!email) return;
|
|
244
|
+
|
|
245
|
+
if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
|
|
246
|
+
console.log(clr(c.red, ' Invalid email. Skipped.'));
|
|
247
|
+
return;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
process.stdout.write(clr(c.dim, ' Creating key...'));
|
|
251
|
+
|
|
252
|
+
try {
|
|
253
|
+
const res = await fetch('https://poc-backend.amdal-dev.workers.dev/api/keys/create', {
|
|
254
|
+
method: 'POST',
|
|
255
|
+
headers: { 'Content-Type': 'application/json' },
|
|
256
|
+
body: JSON.stringify({ email, source: 'cli' }),
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
const data = await res.json();
|
|
260
|
+
|
|
261
|
+
if (data.key) {
|
|
262
|
+
await writeApiKey(data.key);
|
|
263
|
+
_cachedHasKey = true;
|
|
264
|
+
console.log(clr(c.green, ' ✓ Saved to ~/.commit/config'));
|
|
265
|
+
console.log(clr(c.dim, ` Backup sent to ${email}`));
|
|
266
|
+
console.log();
|
|
267
|
+
console.log(clr(c.bold, ' Next steps:'));
|
|
268
|
+
console.log(clr(c.dim, ' • ') + clr(c.cyan, 'poc status') + clr(c.dim, ' — check your account'));
|
|
269
|
+
if (critPkgs.length > 0) {
|
|
270
|
+
console.log(clr(c.dim, ' • ') + clr(c.cyan, `poc watch ${critPkgs[0].name}`) + clr(c.dim, ' — start monitoring (Pro)'));
|
|
271
|
+
}
|
|
272
|
+
console.log(clr(c.dim, ' • ') + clr(c.cyan, 'poc init') + clr(c.dim, ' — add CI gate to this project'));
|
|
273
|
+
} else if (data.message) {
|
|
274
|
+
console.log(clr(c.green, ` ✓ ${data.message}`));
|
|
275
|
+
} else {
|
|
276
|
+
console.log(clr(c.red, ` Failed: ${JSON.stringify(data)}`));
|
|
277
|
+
}
|
|
278
|
+
} catch (err) {
|
|
279
|
+
console.log(clr(c.red, ` Error: ${err.message}`));
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
console.log();
|
|
283
|
+
}
|
|
284
|
+
|
|
203
285
|
function printHelp() {
|
|
204
286
|
console.log(`
|
|
205
|
-
${clr(c.bold, 'proof-of-commitment')} v1.
|
|
287
|
+
${clr(c.bold, 'proof-of-commitment')} v1.13.0 — supply chain risk scorer
|
|
206
288
|
|
|
207
289
|
${clr(c.bold, 'Usage:')}
|
|
208
290
|
npx proof-of-commitment Auto-detect manifest in current dir
|
|
@@ -785,7 +867,7 @@ async function cmdLogin(keyArg) {
|
|
|
785
867
|
console.log(clr(c.dim, ' poc watchlist View monitored packages'));
|
|
786
868
|
console.log(clr(c.dim, ' poc unwatch <package> Remove from monitoring'));
|
|
787
869
|
} else {
|
|
788
|
-
console.log(clr(c.dim, ' Upgrade to Pro for monitoring + alerts: https://getcommit.dev/pricing'));
|
|
870
|
+
console.log(clr(c.dim, ' Upgrade to Pro for monitoring + alerts: https://getcommit.dev/pricing?utm_source=cli'));
|
|
789
871
|
}
|
|
790
872
|
console.log();
|
|
791
873
|
}
|
|
@@ -864,7 +946,7 @@ async function cmdWatch(pkg, ecosystem) {
|
|
|
864
946
|
const key = await readApiKey();
|
|
865
947
|
if (!key) {
|
|
866
948
|
console.error(clr(c.red, 'No API key found. Set COMMIT_API_KEY or add api_key=<key> to ~/.commit/config'));
|
|
867
|
-
console.error(clr(c.dim, 'Get a key at https://getcommit.dev/pricing'));
|
|
949
|
+
console.error(clr(c.dim, 'Get a key at https://getcommit.dev/pricing?utm_source=cli'));
|
|
868
950
|
process.exit(1);
|
|
869
951
|
}
|
|
870
952
|
|
|
@@ -1129,7 +1211,7 @@ ${rows}
|
|
|
1129
1211
|
<div class="footer">
|
|
1130
1212
|
<span>Generated by <a href="${WEB}" target="_blank">proof-of-commitment</a></span>
|
|
1131
1213
|
<span><a href="https://github.com/piiiico/commit-action" target="_blank">GitHub Action</a></span>
|
|
1132
|
-
<span><a href="https://getcommit.dev/pricing" target="_blank">Commit Pro</a></span>
|
|
1214
|
+
<span><a href="https://getcommit.dev/pricing?utm_source=cli&utm_medium=report" target="_blank">Commit Pro</a></span>
|
|
1133
1215
|
</div>
|
|
1134
1216
|
<script>
|
|
1135
1217
|
function copyMd() {
|
|
@@ -1385,7 +1467,7 @@ jobs:
|
|
|
1385
1467
|
console.log(clr(c.white, ' 2. Push to trigger the existing workflow'));
|
|
1386
1468
|
}
|
|
1387
1469
|
console.log(clr(c.dim, `\n Want daily monitoring + alerts? Get a free key:`));
|
|
1388
|
-
console.log(clr(c.cyan, ' https://getcommit.dev/get-started'));
|
|
1470
|
+
console.log(clr(c.cyan, ' https://getcommit.dev/get-started?utm_source=cli'));
|
|
1389
1471
|
console.log(clr(c.dim, ' Then run: ') + clr(c.cyan, 'poc login') + clr(c.dim, ' + ') + clr(c.cyan, 'poc watch <package>\n'));
|
|
1390
1472
|
}
|
|
1391
1473
|
|
|
@@ -1654,6 +1736,7 @@ async function main() {
|
|
|
1654
1736
|
const displayed = allResults.slice(0, MAX_DISPLAY);
|
|
1655
1737
|
const criticalTotal = allResults.filter(r => hasCritical(r.riskFlags)).length;
|
|
1656
1738
|
printTable(displayed, { totalScanned: allResults.length, totalCritical: criticalTotal, lockfile: true });
|
|
1739
|
+
await inlineSignup(displayed);
|
|
1657
1740
|
if (shouldFail(allResults, failOn)) {
|
|
1658
1741
|
console.error(clr(c.red + c.bold, `\n✗ --fail-on=${failOn} threshold met. Exit 1.`));
|
|
1659
1742
|
process.exit(1);
|
|
@@ -1684,6 +1767,7 @@ async function main() {
|
|
|
1684
1767
|
}
|
|
1685
1768
|
|
|
1686
1769
|
printTable(allResults);
|
|
1770
|
+
await inlineSignup(allResults);
|
|
1687
1771
|
if (shouldFail(allResults, failOn)) {
|
|
1688
1772
|
console.error(clr(c.red + c.bold, `✗ --fail-on=${failOn} threshold met. Exit 1.`));
|
|
1689
1773
|
process.exit(1);
|