aztrx-cli 0.4.1 → 0.4.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/dist/cli.js +8 -6
- package/dist/core/orchestrator.js +7 -2
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -64,8 +64,15 @@ async function detectUrl(repoRoot) {
|
|
|
64
64
|
function suggestNext(findings, opts) {
|
|
65
65
|
if (opts.dryRun || opts.crashTest || findings.length === 0)
|
|
66
66
|
return;
|
|
67
|
-
const crashOrError = findings.some((f) => f.severity === "crash" || f.severity === "error");
|
|
68
67
|
const alreadyFixing = opts.heal || opts.fix || opts.magicFix;
|
|
68
|
+
// Server-side 5xx → point at the server fuzzer. `--fix` patches frontend code,
|
|
69
|
+
// so it can't help with a 502/500 from the server.
|
|
70
|
+
const serverError = findings.some((f) => f.type === "network_5xx");
|
|
71
|
+
if (serverError && !opts.httpFuzz) {
|
|
72
|
+
console.log(pc.dim("Tip: these are server-side 5xx — run with --http-fuzz to map the server attack surface"));
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
const crashOrError = findings.some((f) => f.severity === "crash" || f.severity === "error");
|
|
69
76
|
if (crashOrError && !alreadyFixing) {
|
|
70
77
|
if (opts.repro) {
|
|
71
78
|
console.log(pc.dim("Tip: run with --fix to attempt a closed-loop fix"));
|
|
@@ -73,11 +80,6 @@ function suggestNext(findings, opts) {
|
|
|
73
80
|
else {
|
|
74
81
|
console.log(pc.dim("Tip: run with --repro to prove these with a runnable spec, or --fix to fix them end-to-end"));
|
|
75
82
|
}
|
|
76
|
-
return;
|
|
77
|
-
}
|
|
78
|
-
const serverError = findings.some((f) => f.type === "network_5xx");
|
|
79
|
-
if (serverError && !opts.httpFuzz) {
|
|
80
|
-
console.log(pc.dim("Tip: run with --http-fuzz to map the server-side attack surface"));
|
|
81
83
|
}
|
|
82
84
|
}
|
|
83
85
|
program
|
|
@@ -227,15 +227,15 @@ export async function run(options) {
|
|
|
227
227
|
// it in a sandboxed worktree, and verify the bug stops reproducing. Opt-in;
|
|
228
228
|
// the patch is only ever handed to a human for review, never committed.
|
|
229
229
|
if (options.heal) {
|
|
230
|
-
const
|
|
230
|
+
const reproducible = findings.filter((f) => (f.severity === "crash" || f.severity === "error") &&
|
|
231
231
|
// A `network_5xx` finding heals only when its 500 body leaked a server
|
|
232
232
|
// stack (→ an own-code source location); heal then boots the patched app
|
|
233
233
|
// to verify. `network_timeout` stays excluded — it needs a time-based
|
|
234
234
|
// repro first.
|
|
235
235
|
f.type !== "network_timeout" &&
|
|
236
|
-
f.mappedLocation?.isOwnCode &&
|
|
237
236
|
f.repro &&
|
|
238
237
|
f.repro.verdict !== "unreliable");
|
|
238
|
+
const healTargets = reproducible.filter((f) => f.mappedLocation?.isOwnCode);
|
|
239
239
|
if (healTargets.length) {
|
|
240
240
|
say(pc.cyan("— Closed-loop healing (redact → generate → gate → sandbox → test → verify) —"));
|
|
241
241
|
emitPhase("heal");
|
|
@@ -295,6 +295,11 @@ export async function run(options) {
|
|
|
295
295
|
}
|
|
296
296
|
}
|
|
297
297
|
}
|
|
298
|
+
else if (reproducible.length > 0) {
|
|
299
|
+
// Reproducible crashes, but none mapped to source (wrong --repo?) — tell the
|
|
300
|
+
// user rather than silently doing nothing.
|
|
301
|
+
say(pc.yellow(`Found ${reproducible.length} reproducible crash(es) but couldn't map them to source files. Run from your project root (or pass --repo <dir>) so --fix can read the code.`));
|
|
302
|
+
}
|
|
298
303
|
}
|
|
299
304
|
const reportPath = writeReport(repoRoot, url, findings);
|
|
300
305
|
say(pc.dim(`Report: ${path.relative(repoRoot, reportPath)}`));
|