pqcheck 0.16.16 → 0.16.17
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 +1 -1
- package/bin/pqcheck.js +42 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
[](https://www.npmjs.com/package/pqcheck)
|
|
9
9
|
[](./LICENSE)
|
|
10
10
|
|
|
11
|
-
> **Latest: v0.16.
|
|
11
|
+
> **Latest: v0.16.17** — fail-loud AI guard now covers the no-baseline first-deploy fallback. `pqcheck deploy-check <new-domain> --ai` previously exited 3 with bare `error: /api/scan returned 429` if the very first scan got rate-limited — no `CIPHERWAKE_AI_GUARD_RESULT` block, leaving the calling AI agent with no `ship_decision` to route on. Now every error path in that fallback emits a `ship_decision=review` block with a status-specific `top_issue` code. [Full changelog →](./CHANGELOG.md)
|
|
12
12
|
|
|
13
13
|
## Two ways to use it
|
|
14
14
|
|
package/bin/pqcheck.js
CHANGED
|
@@ -3051,12 +3051,51 @@ async function runScanBasedDeployCheck(domain, args) {
|
|
|
3051
3051
|
try {
|
|
3052
3052
|
resp = await fetch(`${API_BASE}/api/scan?domain=${encodeURIComponent(domain)}`, { headers });
|
|
3053
3053
|
} catch (err) {
|
|
3054
|
+
// v0.16.17 — the v0.16.13 fail-loud AI guard fix was applied to the main
|
|
3055
|
+
// trust-diff deploy-check path but missed THIS fallback path (no-baseline
|
|
3056
|
+
// first-deploy), so a network blip on the very first `pqcheck deploy-check
|
|
3057
|
+
// <new-domain> --ai` exited 3 with no CIPHERWAKE_AI_GUARD_RESULT block.
|
|
3058
|
+
// The calling AI agent then had no ship_decision to route on and could
|
|
3059
|
+
// silently continue shipping — exactly the failure mode the protocol
|
|
3060
|
+
// exists to prevent. Same emit-block-and-exit pattern as trust-diff.
|
|
3054
3061
|
console.error(color("red", `error: network failure calling /api/scan: ${err.message}`));
|
|
3055
|
-
|
|
3062
|
+
return emitAiGuardReviewAndExit(args, {
|
|
3063
|
+
code: "deploy_check_fetch_failed",
|
|
3064
|
+
message: `Network failure calling /api/scan: ${err?.message || "fetch failed"}`,
|
|
3065
|
+
exitCode: 3,
|
|
3066
|
+
});
|
|
3056
3067
|
}
|
|
3057
3068
|
if (!resp.ok) {
|
|
3058
|
-
|
|
3059
|
-
|
|
3069
|
+
// v0.16.17 — same fix as above for the HTTP-non-OK path. The 429 case
|
|
3070
|
+
// is especially load-bearing: a brand new AI-coder workflow trying its
|
|
3071
|
+
// first deploy-check on a fresh project will commonly hit per-IP rate
|
|
3072
|
+
// limits, get a bare `error: /api/scan returned 429`, and exit 3 with no
|
|
3073
|
+
// guard block. The AI agent then has nothing to parse. Emitting a
|
|
3074
|
+
// ship_decision=review block with a quota-specific error code lets the
|
|
3075
|
+
// agent surface the rate-limit problem to the user instead of silently
|
|
3076
|
+
// continuing. Surface the body message + auth hint when available so
|
|
3077
|
+
// the user knows whether to wait or get an API key.
|
|
3078
|
+
const body = await safeJSON(resp);
|
|
3079
|
+
const statusLabel = resp.status === 429
|
|
3080
|
+
? "rate-limited"
|
|
3081
|
+
: resp.status === 401 || resp.status === 403
|
|
3082
|
+
? "auth failed"
|
|
3083
|
+
: `${resp.status}`;
|
|
3084
|
+
console.error(color("red", `error: /api/scan returned ${resp.status} (${statusLabel})`));
|
|
3085
|
+
if (body?.message) console.error(color("dim", body.message));
|
|
3086
|
+
if (body?.hint) console.error(color("dim", body.hint));
|
|
3087
|
+
if (resp.status === 429) {
|
|
3088
|
+
console.error(color("dim", "Higher quota via free API key (no card): https://cipherwake.io/account#api-keys"));
|
|
3089
|
+
}
|
|
3090
|
+
const code = resp.status === 429
|
|
3091
|
+
? "deploy_check_rate_limited"
|
|
3092
|
+
: resp.status === 401 || resp.status === 403
|
|
3093
|
+
? "deploy_check_auth_failed"
|
|
3094
|
+
: "deploy_check_scan_failed";
|
|
3095
|
+
const message = resp.status === 429
|
|
3096
|
+
? (body?.message || "Per-IP rate limit hit on /api/scan. Wait ~1 minute or use an API key for higher quota.")
|
|
3097
|
+
: body?.message || `Cipherwake /api/scan returned ${resp.status}.`;
|
|
3098
|
+
return emitAiGuardReviewAndExit(args, { code, message, exitCode: 3 });
|
|
3060
3099
|
}
|
|
3061
3100
|
const report = await resp.json();
|
|
3062
3101
|
const findings = Array.isArray(report.findings) ? report.findings : [];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pqcheck",
|
|
3
|
-
"version": "0.16.
|
|
3
|
+
"version": "0.16.17",
|
|
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",
|