proof-of-commitment 1.12.1 → 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 +73 -2
- 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
|
*/
|
|
@@ -213,9 +213,78 @@ function printTable(results, { totalScanned, totalCritical, lockfile } = {}) {
|
|
|
213
213
|
console.log();
|
|
214
214
|
}
|
|
215
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
|
+
|
|
216
285
|
function printHelp() {
|
|
217
286
|
console.log(`
|
|
218
|
-
${clr(c.bold, 'proof-of-commitment')} v1.
|
|
287
|
+
${clr(c.bold, 'proof-of-commitment')} v1.13.0 — supply chain risk scorer
|
|
219
288
|
|
|
220
289
|
${clr(c.bold, 'Usage:')}
|
|
221
290
|
npx proof-of-commitment Auto-detect manifest in current dir
|
|
@@ -1667,6 +1736,7 @@ async function main() {
|
|
|
1667
1736
|
const displayed = allResults.slice(0, MAX_DISPLAY);
|
|
1668
1737
|
const criticalTotal = allResults.filter(r => hasCritical(r.riskFlags)).length;
|
|
1669
1738
|
printTable(displayed, { totalScanned: allResults.length, totalCritical: criticalTotal, lockfile: true });
|
|
1739
|
+
await inlineSignup(displayed);
|
|
1670
1740
|
if (shouldFail(allResults, failOn)) {
|
|
1671
1741
|
console.error(clr(c.red + c.bold, `\n✗ --fail-on=${failOn} threshold met. Exit 1.`));
|
|
1672
1742
|
process.exit(1);
|
|
@@ -1697,6 +1767,7 @@ async function main() {
|
|
|
1697
1767
|
}
|
|
1698
1768
|
|
|
1699
1769
|
printTable(allResults);
|
|
1770
|
+
await inlineSignup(allResults);
|
|
1700
1771
|
if (shouldFail(allResults, failOn)) {
|
|
1701
1772
|
console.error(clr(c.red + c.bold, `✗ --fail-on=${failOn} threshold met. Exit 1.`));
|
|
1702
1773
|
process.exit(1);
|