pqcheck 0.16.0 → 0.16.2
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/bin/cipherwake-statusline.js +12 -0
- package/bin/pqcheck.js +108 -31
- package/package.json +1 -1
|
@@ -121,6 +121,18 @@ const sevSegment = (!isUnreachable && max_severity && max_severity !== "none")
|
|
|
121
121
|
? ` · ${String(max_severity).toUpperCase()}`
|
|
122
122
|
: "";
|
|
123
123
|
|
|
124
|
+
// v0.16.2 — drift narrative suffix. "stable 14d" / "drifted 2d ago" / "now".
|
|
125
|
+
// Sourced from state.lastChanged (smartCache populates) so the customer
|
|
126
|
+
// sees time-series anchor at a glance, not just a single-point snapshot.
|
|
127
|
+
let stabilitySegment = "";
|
|
128
|
+
if (!isUnreachable && state.lastChanged) {
|
|
129
|
+
const dms = Date.now() - new Date(state.lastChanged).getTime();
|
|
130
|
+
const days = Math.floor(dms / 86400000);
|
|
131
|
+
if (days <= 0) stabilitySegment = " · drifted today";
|
|
132
|
+
else if (days < 7) stabilitySegment = ` · drifted ${days}d ago`;
|
|
133
|
+
else stabilitySegment = ` · stable ${days}d`;
|
|
134
|
+
}
|
|
135
|
+
|
|
124
136
|
process.stdout.write(
|
|
125
137
|
c(cdec, "◆") +
|
|
126
138
|
" " +
|
package/bin/pqcheck.js
CHANGED
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
})();
|
|
25
25
|
|
|
26
26
|
const API_BASE = process.env.PQCHECK_API_BASE || "https://cipherwake.io";
|
|
27
|
-
const VERSION = "0.16.
|
|
27
|
+
const VERSION = "0.16.2";
|
|
28
28
|
|
|
29
29
|
// API-key support — paid tiers (Starter $29 / Growth $79 / Scale $199) get
|
|
30
30
|
// per-account monthly quotas instead of the per-IP rate limit. Set via:
|
|
@@ -831,11 +831,13 @@ function countVerifiedSignals(report) {
|
|
|
831
831
|
if (report?.sourceMaps?.reachable) cats.push("source maps");
|
|
832
832
|
// 6. TLS posture
|
|
833
833
|
if (report?.publicSurface?.tlsVersion || report?.tlsVersion) cats.push("TLS");
|
|
834
|
-
// 7. Mixed content —
|
|
835
|
-
// publicDeps
|
|
836
|
-
if (report?.publicDeps?.fetched) cats.push("mixed-content");
|
|
834
|
+
// 7. Mixed content — v0.16.2 promoted to dedicated probe; falls back to
|
|
835
|
+
// publicDeps inference when explicit field missing.
|
|
836
|
+
if (report?.mixedContent?.probed || report?.publicDeps?.fetched) cats.push("mixed-content");
|
|
837
837
|
// 8. Subdomain scale (from CT log scan)
|
|
838
838
|
if (typeof report?.publicSurface?.subdomainCount === "number") cats.push("subdomain scale");
|
|
839
|
+
// 9. Protected paths (v0.16.2 — the headline feature)
|
|
840
|
+
if (report?.protectedPaths?.probed) cats.push("protected paths");
|
|
839
841
|
return { count: cats.length, categories: cats };
|
|
840
842
|
}
|
|
841
843
|
|
|
@@ -2762,19 +2764,39 @@ async function runScanBasedDeployCheck(domain, args) {
|
|
|
2762
2764
|
];
|
|
2763
2765
|
}
|
|
2764
2766
|
|
|
2767
|
+
// v0.16.0 high-yield rendering — same shape as runOneScan but with the
|
|
2768
|
+
// "first-deploy" context line above the brand header (since this path
|
|
2769
|
+
// fires only when there's no baseline to diff against).
|
|
2770
|
+
const verbose = isVerboseMode(args);
|
|
2771
|
+
const highSevFindings = findings.filter((f) => severityRank(f.severity) >= 3);
|
|
2772
|
+
const alertCount = highSevFindings.length;
|
|
2773
|
+
|
|
2765
2774
|
console.log("");
|
|
2766
2775
|
console.log(color("dim", ` ℹ first deploy-check for ${domain} — using current scan state (no baseline yet to diff against)`));
|
|
2767
2776
|
console.log("");
|
|
2768
|
-
console.log(
|
|
2769
|
-
|
|
2770
|
-
|
|
2771
|
-
|
|
2772
|
-
|
|
2773
|
-
|
|
2774
|
-
|
|
2775
|
-
|
|
2776
|
-
|
|
2777
|
-
|
|
2777
|
+
console.log(formatBrandHeader(domain));
|
|
2778
|
+
console.log("");
|
|
2779
|
+
console.log(formatDecisionPulse({ shipDecision, alertCount, unreachable, diffContext: true }));
|
|
2780
|
+
|
|
2781
|
+
if (unreachable) {
|
|
2782
|
+
console.log(formatAiBody({ topIssue, whyMatters, nextActions }));
|
|
2783
|
+
} else {
|
|
2784
|
+
if (alertCount > 0) {
|
|
2785
|
+
const alerts = formatAlertsLine(highSevFindings);
|
|
2786
|
+
if (alerts) console.log(alerts);
|
|
2787
|
+
}
|
|
2788
|
+
const tpl = formatTrustPostureLine(report);
|
|
2789
|
+
if (tpl) console.log(tpl);
|
|
2790
|
+
const vsl = formatVerifiedSignalsLine(report);
|
|
2791
|
+
if (vsl) console.log(vsl);
|
|
2792
|
+
if (verbose) {
|
|
2793
|
+
console.log("");
|
|
2794
|
+
console.log(formatHighYieldVerbose(report));
|
|
2795
|
+
} else {
|
|
2796
|
+
console.log(color("dim", " Run with --verbose to see all verified signals."));
|
|
2797
|
+
}
|
|
2798
|
+
}
|
|
2799
|
+
|
|
2778
2800
|
console.log(formatAiFooterBlock({
|
|
2779
2801
|
status: shipDecision,
|
|
2780
2802
|
domain,
|
|
@@ -2910,16 +2932,41 @@ async function runTrustDiffCommand(args) {
|
|
|
2910
2932
|
`If not intentional: revert the deploy or investigate the drift source.`,
|
|
2911
2933
|
];
|
|
2912
2934
|
|
|
2913
|
-
|
|
2914
|
-
|
|
2935
|
+
// v0.16.0 high-yield rendering for trust-diff.
|
|
2936
|
+
const verbose = isVerboseMode(args);
|
|
2937
|
+
const diffNoChange = deltas.length === 0;
|
|
2938
|
+
const fakeReport = {
|
|
2915
2939
|
domain,
|
|
2916
|
-
|
|
2917
|
-
dbr: result.current_score,
|
|
2940
|
+
score: result.current_score,
|
|
2918
2941
|
grade: result.current_grade,
|
|
2919
|
-
|
|
2920
|
-
|
|
2921
|
-
}
|
|
2922
|
-
|
|
2942
|
+
_meta: { lastChanged: result.last_changed },
|
|
2943
|
+
sectorRanking: result.sectorRanking,
|
|
2944
|
+
};
|
|
2945
|
+
|
|
2946
|
+
console.log("");
|
|
2947
|
+
console.log(formatBrandHeader(domain));
|
|
2948
|
+
console.log("");
|
|
2949
|
+
console.log(formatDecisionPulse({ shipDecision, alertCount: deltas.length, unreachable: false, diffContext: true }));
|
|
2950
|
+
|
|
2951
|
+
if (deltas.length > 0) {
|
|
2952
|
+
// Surface top deltas as alerts
|
|
2953
|
+
const alertFindings = deltas.slice(0, 3).map((d) => ({
|
|
2954
|
+
severity: d.severity || "medium",
|
|
2955
|
+
title: d.title || d.what_changed || d.type || "drift",
|
|
2956
|
+
id: d.id,
|
|
2957
|
+
}));
|
|
2958
|
+
const alerts = formatAlertsLine(alertFindings);
|
|
2959
|
+
if (alerts) console.log(alerts);
|
|
2960
|
+
if (deltas.length > 3) console.log(color("dim", ` +${deltas.length - 3} more (run with --verbose)`));
|
|
2961
|
+
}
|
|
2962
|
+
const tpl = formatTrustPostureLine(fakeReport);
|
|
2963
|
+
if (tpl) console.log(tpl);
|
|
2964
|
+
const vsl = formatVerifiedSignalsLine(fakeReport, { diffNoChange });
|
|
2965
|
+
if (vsl) console.log(vsl);
|
|
2966
|
+
if (!verbose) {
|
|
2967
|
+
console.log(color("dim", " Run with --verbose to see all verified signals."));
|
|
2968
|
+
}
|
|
2969
|
+
|
|
2923
2970
|
console.log(formatAiFooterBlock({
|
|
2924
2971
|
status: shipDecision,
|
|
2925
2972
|
domain,
|
|
@@ -3123,16 +3170,46 @@ async function runPreviewDiffCommand(args) {
|
|
|
3123
3170
|
`Each "- CSP weakened" or "~ HSTS weakened" reduces production safety.`,
|
|
3124
3171
|
];
|
|
3125
3172
|
|
|
3126
|
-
|
|
3127
|
-
|
|
3128
|
-
|
|
3129
|
-
|
|
3130
|
-
|
|
3173
|
+
// v0.16.2 high-yield rendering for preview-diff.
|
|
3174
|
+
const verbose = isVerboseMode(args);
|
|
3175
|
+
const diffNoChange = !hasUnexpectedDiff;
|
|
3176
|
+
const headerDomain = result?.production?.domain || productionUrl;
|
|
3177
|
+
const fakeReport = {
|
|
3178
|
+
domain: headerDomain,
|
|
3179
|
+
score: prevScore,
|
|
3131
3180
|
grade: result?.preview?.grade,
|
|
3132
|
-
|
|
3133
|
-
|
|
3134
|
-
}
|
|
3135
|
-
|
|
3181
|
+
_meta: { lastChanged: result?.production?.lastChanged },
|
|
3182
|
+
sectorRanking: result?.production?.sectorRanking,
|
|
3183
|
+
};
|
|
3184
|
+
// Render top deltas as alert lines (1 per finding, max 3)
|
|
3185
|
+
const deltaLines = summaryLines.filter((l) => !/no meaningful/i.test(l));
|
|
3186
|
+
|
|
3187
|
+
console.log("");
|
|
3188
|
+
console.log(formatBrandHeader(headerDomain));
|
|
3189
|
+
console.log("");
|
|
3190
|
+
console.log(formatDecisionPulse({ shipDecision, alertCount: deltaLines.length, unreachable: false, diffContext: true }));
|
|
3191
|
+
|
|
3192
|
+
if (deltaLines.length > 0) {
|
|
3193
|
+
for (const dl of deltaLines.slice(0, 3)) {
|
|
3194
|
+
const sym = dl.startsWith("⛔") || dl.startsWith("-") ? "red" : dl.startsWith("⚠") || dl.startsWith("~") ? "yellow" : "dim";
|
|
3195
|
+
console.log(color(sym, dl));
|
|
3196
|
+
}
|
|
3197
|
+
if (deltaLines.length > 3) console.log(color("dim", ` +${deltaLines.length - 3} more (run with --verbose)`));
|
|
3198
|
+
}
|
|
3199
|
+
const tpl = formatTrustPostureLine(fakeReport);
|
|
3200
|
+
if (tpl) console.log(tpl);
|
|
3201
|
+
const vsl = formatVerifiedSignalsLine(fakeReport, { diffNoChange });
|
|
3202
|
+
if (vsl) console.log(vsl);
|
|
3203
|
+
if (!verbose) {
|
|
3204
|
+
console.log(color("dim", " Run with --verbose to see all verified signals."));
|
|
3205
|
+
}
|
|
3206
|
+
|
|
3207
|
+
// (Old banner + body removed in v0.16.2; new high-yield layout above
|
|
3208
|
+
// replaces them. AI footer still lands below for downstream agents.)
|
|
3209
|
+
if (verbose) {
|
|
3210
|
+
console.log("");
|
|
3211
|
+
console.log(formatAiBody({ topIssue, whyMatters, nextActions }));
|
|
3212
|
+
}
|
|
3136
3213
|
console.log(formatAiFooterBlock({
|
|
3137
3214
|
status: shipDecision,
|
|
3138
3215
|
domain: result?.production?.domain || productionUrl,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pqcheck",
|
|
3
|
-
"version": "0.16.
|
|
3
|
+
"version": "0.16.2",
|
|
4
4
|
"description": "Deploy gate for AI-coded web apps. `pqcheck deploy-check --ai` returns ship_decision=pass|review|block for Claude Code / Cursor / Copilot / Aider to gate deploys before they ship. Anonymous, no signup, free for first use.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai-coder",
|