aztrx-cli 0.3.0 → 0.4.1

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 CHANGED
@@ -1,144 +1,148 @@
1
1
  # <img src="media/logo.svg" width="28" height="32" alt="Aztrx logo" align="absmiddle" /> Aztrx AI
2
2
 
3
- > **Autonomous runtime stress-tester, deterministic bug minimizer, human-language explainer, and self-healing engine for web applications.**
3
+ > **Catch the runtime crash your Error Boundary hid and prove it with a test, not a log line.**
4
4
 
5
5
  [![Node.js](https://img.shields.io/badge/Node.js-%3E%3D18-green.svg?style=flat-square)](https://nodejs.org)
6
6
  [![License: Apache 2.0](https://img.shields.io/badge/License-Apache%202.0-blue.svg?style=flat-square)](LICENSE)
7
7
 
8
- Aztrx AI drives your web app like a hostile user — clicking, entering boundary data, and racing asynchronous UI states. When a runtime crash occurs (even one swallowed by a React Error Boundary), Aztrx AI intercepts it via the Chrome DevTools Protocol, maps it back to the exact source line, shrinks the interaction trace to the bare minimum with **ddmin**, and emits an executable, standalone **Playwright test** that proves the bug not a log line.
9
-
10
- ![aztrx demo](media/demo.gif)
11
-
12
- ---
13
-
14
- ## Run it
8
+ Aztrx AI finds **runtime** bugs, not security holes. It drives your web app like a hostile
9
+ user and catches the crashes that ship to real users — *including ones a React Error Boundary
10
+ swallows* (the errors `window.onerror` never sees). Each crash comes back as an exact source
11
+ line plus an executable **Playwright repro** that fails `3/3` times. Then it fixes it.
15
12
 
16
13
  ```bash
17
- npx aztrx-cli run http://localhost:3000
14
+ npx aztrx-cli run http://localhost:3000 # find crashes — zero setup, no key
15
+ npx aztrx-cli run http://localhost:3000 --fix # fix them — free for common bugs
18
16
  ```
19
17
 
20
- That's the whole setup — no install, no config, no account, no API key. Point it at your
21
- running dev server and it finds the crashes. It drives Chromium through Playwright (the
22
- first run downloads the browser automatically).
18
+ ![aztrx demo](media/demo.gif)
23
19
 
24
- What that one command gives you:
20
+ ---
25
21
 
26
- - **Sees swallowed errors.** Error Boundaries and `window.onerror` miss the errors your app *catches*. Aztrx AI reads the real throw-site stack off the `Error` object — a crash you've never seen in your logs becomes a finding you can't ignore.
27
- - **Proves, not reports.** Every crash/error finding ships with an executable `.spec.ts` repro and a flake-rate verdict — `[deterministic 5/5]`, `[flaky 3/5]`, or `[unreliable]`.
28
- - **Safe by default.** A deny-by-default network guard blocks off-origin calls, a destructive-action deny-list refuses to click "delete", "pay", or "logout", and nothing leaves your machine unless you opt in.
22
+ ## Why Aztrx AI
29
23
 
30
- More ways to run all optional flags on top of the same command:
24
+ - **Sees swallowed errors.** Error Boundaries and `window.onerror` miss the errors your app *catches*. Aztrx reads the real throw-site stack off the `Error` object — a crash you've never seen in your logs becomes a finding you can't ignore.
25
+ - **Proves, not reports.** Every crash ships with an executable `.spec.ts` repro and a flake-rate verdict — `[deterministic 3/3]`, `[flaky 3/5]`, or `[unreliable]`.
26
+ - **Safe by default.** A deny-by-default network guard blocks off-origin calls, a destructive-action deny-list refuses to click "delete", "pay", or "logout", and nothing leaves your machine unless you opt in.
31
27
 
32
- ```bash
33
- npx aztrx-cli run http://localhost:3000 --fuzz # seeded chaos (replayable)
34
- npx aztrx-cli run http://localhost:3000 --repro # minimize → compile → validate
35
- npx aztrx-cli run http://localhost:3000 --http-fuzz # server-side 5xx hunt
36
- ```
28
+ ---
37
29
 
38
- Prefer a global install?
30
+ ## Quickstart
39
31
 
40
32
  ```bash
41
- npm i -g aztrx-cli
42
- aztrx-cli run http://localhost:3000
33
+ npm i -g aztrx-cli # or use npx — no install needed
34
+
35
+ aztrx-cli run http://localhost:3000 # 1. find the crashes (no key, no account)
36
+ aztrx-cli run http://localhost:3000 --repro # 2. prove them with an executable test
37
+ aztrx-cli run http://localhost:3000 --fix # 3. fix them
43
38
  ```
44
39
 
40
+ Point it at any running dev server. It drives Chromium through Playwright (the first run
41
+ downloads the browser automatically).
42
+
45
43
  ---
46
44
 
47
- ## Fix it, not just find it
45
+ ## Fix it free for common crashes
46
+
47
+ `--fix` has two engines:
48
48
 
49
- The only feature that needs a key. `--fix` hands the crash to an LLM and applies a
50
- verified patch to your working tree. Anthropic by default set `ANTHROPIC_API_KEY`:
49
+ **1. Free, no key.** For the most common crash `Cannot read properties of
50
+ undefined/null` a built-in rule adds `?.` (optional chaining) and applies the fix. No LLM,
51
+ no key, no cost:
51
52
 
52
53
  ```bash
53
- export ANTHROPIC_API_KEY="your-api-key"
54
- npx aztrx-cli run http://localhost:3000 --fix # find → explain → heal → apply
55
- npx aztrx-cli run http://localhost:3000 --fix --yes # non-interactive (CI)
54
+ aztrx-cli run http://localhost:3000 --fix # works out of the box for null/undefined derefs
56
55
  ```
57
56
 
58
- Or use **any model** Grok, DeepSeek, Gemini, GPT, Kimi, Mistral, OpenRouter, or a
59
- local Ollama/vLLM. Point it at any OpenAI-compatible `/v1` endpoint:
57
+ **2. Your model, for complex bugs.** Logic errors, races, and anything the rule can't handle
58
+ point it at any model:
60
59
 
61
60
  ```bash
62
- export AZTRX_API_BASE="https://openrouter.ai/api/v1" # or api.openai.com/v1, api.x.ai/v1, ...
61
+ # Anthropic
62
+ export ANTHROPIC_API_KEY="sk-ant-..."
63
+
64
+ # or any OpenAI-compatible provider: OpenAI, Grok, DeepSeek, Gemini, Kimi, OpenRouter, Ollama
65
+ export AZTRX_API_BASE="https://openrouter.ai/api/v1"
63
66
  export AZTRX_API_KEY="your-key"
64
- export AZTRX_MODEL="anthropic/claude-sonnet-5" # any model the provider serves
65
- npx aztrx-cli run http://localhost:3000 --fix
67
+ export AZTRX_MODEL="anthropic/claude-sonnet-5"
66
68
  ```
67
69
 
68
- `--fix` chains find explain heal, then asks *"Apply the fix?"* (`y/N`). On yes, the
69
- verified patch lands in your working tree `git diff` shows the result. Aztrx AI never
70
- commits.
71
-
72
- - **`--heal`** — the same pipeline, but stops at a verified `.patch` file (no apply).
73
- - **`--explain`** — a human-language "X-ray" summary of what broke, where, and whether a fix is ready. No key required: it falls back to a deterministic offline summary.
74
-
75
- Every patch is redacted, sandboxed in a detached git worktree, compiler-checked, and gated
76
- on your own test suite before you ever see it.
70
+ Every fix is redacted, sandboxed in a detached git worktree, compiler-checked, and gated on
71
+ your test suite before you see it. Aztrx never commits. `--pr` opens a merge-ready PR;
72
+ `--regression-test` drops the repro into your test dir so the bug can't come back.
77
73
 
78
74
  ---
79
75
 
80
- ## Advanced
76
+ ## More ways to run
81
77
 
82
- Everything else is optional. One line each — the full table is in the [CLI reference](#cli-reference).
78
+ | Flag | What it does |
79
+ | --- | --- |
80
+ | `--fuzz` | coverage-guided chaos fuzz — steers toward code it hasn't reached |
81
+ | `--http-fuzz` | attack the server's endpoints (turns every `5xx` into a repro) |
82
+ | `--swarm` / `--workers N` | parallel detection workers |
83
+ | `--login` | auto-login to test authenticated pages |
84
+ | `--badge` / `--pr-comment` / `--fail-on` | CI artifacts |
85
+ | `modernize <file>` | rewrite legacy JS/TS into modern idiomatic syntax |
86
+ | `studio` | live dashboard on `localhost:7331` |
83
87
 
84
- ### Fuzz harder
85
- `--fuzz` breaks the *client*; `--http-fuzz` attacks the *server* — it harvests your app's
86
- real endpoints and throws hostile requests at them (query overflow, JSON type-confusion,
87
- header injection), turning every `5xx` into an executable repro. When a 500 body leaks a
88
- server stack, `--heal` can even fix it by booting the patched app and replaying the repro.
88
+ Full list: `aztrx-cli run --help`, or the [CLI reference](#cli-reference).
89
89
 
90
- ### Parallel swarm
91
- `--workers 4` fans detection into parallel workers (walk + several fuzz seeds + http-fuzz),
92
- merged by fingerprint. `--swarm` is a hidden alias for `--workers auto`.
90
+ ---
93
91
 
94
- ### Authenticated testing
95
- `--login` detects the login form and signs in before the pass, so every repro runs
96
- authenticated:
92
+ ## Security
97
93
 
98
- ```bash
99
- AZTRX_AUTH_EMAIL=you@example.com AZTRX_AUTH_PASSWORD=secret \
100
- npx aztrx-cli run http://localhost:3000 --login
101
- ```
94
+ - **Local-first.** Nothing leaves your machine unless you opt in.
95
+ - **Never commits.** Fixes land in a detached worktree for your review.
96
+ - **Redacted.** Secrets are stripped from the file, error, and stack before any LLM call.
97
+ - **Deny-by-default network.** Off-origin calls are blocked; destructive clicks (delete/pay/logout) are refused.
98
+ - **`.aztrx/` is gitignored** — repros, reports, and patches stay out of history.
102
99
 
103
- Or `--storage-state <path>` with a saved Playwright state. Use `--login-url` for an
104
- explicit login page, `--allow-host auth.example.com` for a third-party auth backend.
100
+ ---
105
101
 
106
- ### Code modernizer
107
- `npx aztrx-cli modernize src/legacy.js` rewrites legacy JS/TS into modern idiomatic syntax
108
- (`var` → `const`, callbacks → `async`/`await`), applied only after you confirm.
102
+ ## Continuous Integration (GitHub Action)
109
103
 
110
- ### Live studio
111
- `npx aztrx-cli studio` triage findings in a localhost dashboard (binds `127.0.0.1`).
104
+ Runtime gate on every PR — boots your dev server, runs
105
+ `aztrx-cli run --fail-on --repro --heal`, posts a comment with the repro + patch, and fails on
106
+ a crash/error.
112
107
 
113
- ### Config & CI
114
- `npx aztrx-cli init` scaffolds `aztrx.config.ts` and gitignores `.aztrx/`. For a per-PR
115
- runtime gate, use the [GitHub Action](#continuous-integration-github-action). `--pr-comment`
116
- / `--badge` write a PR comment / status badge; `--upload --api-key` streams findings to your
117
- cloud dashboard.
108
+ ```yaml
109
+ # .github/workflows/ci.yml composite action, inline
110
+ on: pull_request
111
+ jobs:
112
+ aztrx:
113
+ runs-on: ubuntu-latest
114
+ permissions: { contents: read, pull-requests: write }
115
+ steps:
116
+ - uses: actions/checkout@v4
117
+ - uses: Aztrx-AI/aztrx@98dbad0f7b6681c7670f7068d01dc0d54813a55f
118
+ with:
119
+ url: http://localhost:3000
120
+ start-command: npm run dev # optional — boot the app in the background
121
+ token: ${{ github.token }}
122
+ anthropic-api-key: ${{ secrets.ANTHROPIC_API_KEY }} # optional — enables --heal
123
+ ```
118
124
 
119
- ### Privacy
120
- Off by default and strictly opt-in. `--telemetry` collects an anonymized tuple locally;
121
- `--share-data` uploads it. `--upload` streams sanitized findings to the cloud. See
122
- [Security & data flow](#security--data-flow) for the invariants.
125
+ A status badge (`--badge`) and PR comment (`--pr-comment`) work the same way — regenerate in
126
+ CI on every push.
123
127
 
124
128
  ---
125
129
 
126
130
  ## CLI reference
127
131
 
128
132
  `aztrx-cli run --help` is grouped by intent (Detect / Prove / Fix / Report & ship / Auth);
129
- the table below is the complete reference — including flags hidden from `--help` (aliases
130
- and niche tuning knobs).
133
+ the table below is the complete reference — including flags hidden from `--help` (aliases and
134
+ niche tuning knobs).
131
135
 
132
136
  | Flag | Description | Default |
133
137
  | --- | --- | --- |
134
138
  | `--fuzz` | Seeded chaos fuzzing instead of the deterministic walk | — |
135
139
  | `--http-fuzz` | Server-side mutation fuzzing — hostile requests against the target origin | — |
136
140
  | `--repro` | Minimize (ddmin) → emit Playwright spec → validate flake rate | — |
137
- | `--heal` | Generate + verify an LLM patch (implies `--repro`) | — |
138
- | `--fix` | Find → explain → heal → apply — the one-command fix (implies `--heal`) | — |
139
- | `--magic-fix` | Deprecated alias for `--fix` (hidden) | — |
141
+ | `--heal` | Generate + verify a fix (implies `--repro`) | — |
142
+ | `--fix` | Find → explain → heal → apply — the one-command fix (free for null/undefined derefs) | — |
140
143
  | `--explain` | Print a human-language summary of the findings | — |
141
144
  | `--yes` / `-y` | Auto-apply verified fixes without prompting (with `--fix`) | — |
145
+ | `--pr` | Open a merge-ready PR with the verified fixes (with `--fix`) | — |
142
146
  | `--lang <code>` | Language for the human-language summary (`en`, `ru`) | `en` |
143
147
  | `--upload` | Stream run findings to the cloud ingest backend | — |
144
148
  | `--api-key <key>` | Auth key for `--upload` / `--share-data` | `$AZTRX_API_KEY` |
@@ -153,18 +157,16 @@ and niche tuning knobs).
153
157
  | `--test-command <cmd>` | Test command run against a healed patch | `npm test` (auto-detected) |
154
158
  | `--test-timeout <ms>` | Timeout for the heal test gate | `300000` |
155
159
  | `--no-test` | Skip the test gate during healing | — |
156
- | `--start-command <cmd>` | Command to boot the app for server healing | `scripts.dev` → `scripts.start` (auto-detected) |
160
+ | `--start-command <cmd>` | Command to boot the app for server healing | `scripts.dev` → `scripts.start` |
157
161
  | `--pr-comment [path]` | Write a GitHub PR markdown comment | `.aztrx/pr-comment.md` |
158
162
  | `--badge [path]` | Write a self-contained SVG status badge | `.aztrx/badge.svg` |
163
+ | `--regression-test [dir]` | Copy validated repro specs into the project test dir | `e2e/` or `tests/` |
159
164
  | `--telemetry` | Collect anonymized tuples locally (opt-in) | — |
160
165
  | `--share-data` | Also upload the sanitized tuples (opt-in) | — |
161
166
  | `--repo <path>` | Root path for sourcemap → source resolution | cwd |
162
167
  | `--allow-host <host>` | Add a host to the network allow-list (repeatable) | — |
163
- | `--storage-state <path>` | Playwright storage-state for authenticated pages (`--auth` is a hidden alias) | — |
168
+ | `--storage-state <path>` | Playwright storage-state for authenticated pages | — |
164
169
  | `--login` | Auto-login before the pass (needs `AZTRX_AUTH_EMAIL`/`AZTRX_AUTH_PASSWORD`) | — |
165
- | `--login-email <email>` | Email for `--login` (hidden — prefer `$AZTRX_AUTH_EMAIL`) | `$AZTRX_AUTH_EMAIL` |
166
- | `--login-password <pass>` | Password for `--login` (hidden — prefer `$AZTRX_AUTH_PASSWORD`) | `$AZTRX_AUTH_PASSWORD` |
167
- | `--login-url <url>` | Explicit login page URL for `--login` (hidden) | current page |
168
170
  | `--fail-on` | Exit `1` if any crash/error finding is present | — |
169
171
  | `--dry-run` | Log planned actions without executing them | — |
170
172
  | `--crash-test` | Throw a deliberate error to verify capture | — |
@@ -178,252 +180,20 @@ Every run writes self-contained artifacts inside `.aztrx/` (gitignored):
178
180
 
179
181
  ```
180
182
  .aztrx/
181
- ├── report.html # zero-CDN interactive triage report
182
- ├── repro/
183
- │ └── 458f6bf71977.spec.ts # minimal, executable Playwright repro
184
- ├── heal/
185
- │ └── fix.patch # gated, compiler-checked fix
186
- ├── events.jsonl # run log, streamed by `aztrx-cli studio`
187
- ├── telemetry/dataset.jsonl # opt-in anonymized tuple dataset
183
+ ├── report.html # interactive triage report
184
+ ├── repro/<id>.spec.ts # minimal, executable Playwright repro
185
+ ├── heal/fix.patch # gated, compiler-checked fix
186
+ ├── events.jsonl # run log (streamed by `aztrx-cli studio`)
188
187
  ├── pr-comment.md # GitHub PR markdown (with --pr-comment)
189
188
  └── badge.svg # status badge (with --badge)
190
189
  ```
191
190
 
192
191
  ---
193
192
 
194
- ## Continuous Integration (GitHub Action)
195
-
196
- Runtime gate on every PR. The action boots your dev server, runs
197
- `aztrx-cli run --fail-on --repro --heal`, posts a markdown comment with the
198
- deterministic repro + gated patch, and fails the check on a crash/error.
199
-
200
- ```yaml
201
- # .github/workflows/ci.yml — composite action, inline
202
- on: pull_request
203
- jobs:
204
- aztrx:
205
- runs-on: ubuntu-latest
206
- permissions: { contents: read, pull-requests: write }
207
- steps:
208
- - uses: actions/checkout@v4
209
- - uses: DanisChaparov/aztrx@ee586a4410240efb7ed211ab0e1bf9d188361efa
210
- with:
211
- url: http://localhost:3000
212
- start-command: npm run dev # optional — boot the app in the background
213
- token: ${{ github.token }}
214
- anthropic-api-key: ${{ secrets.ANTHROPIC_API_KEY }} # optional — enables --heal
215
- ```
216
-
217
- Or as a reusable workflow:
218
-
219
- ```yaml
220
- on: pull_request
221
- jobs:
222
- aztrx:
223
- uses: DanisChaparov/aztrx/.github/workflows/aztrx-pr.yml@ee586a4410240efb7ed211ab0e1bf9d188361efa
224
- with:
225
- url: http://localhost:3000
226
- start-command: npm run dev
227
- secrets:
228
- anthropic-api-key: ${{ secrets.ANTHROPIC_API_KEY }}
229
- ```
230
-
231
- ---
232
-
233
- ## Status badge
234
-
235
- Hang a live badge in your README that reflects your *actual* crash/error state —
236
- not a static "protected" sticker.
237
-
238
- ```bash
239
- npx aztrx-cli run http://localhost:3000 --badge badge.svg
240
- ```
241
-
242
- ```markdown
243
- [![aztrx](badge.svg)](https://github.com/DanisChaparov/aztrx)
244
- ```
245
-
246
- The badge is a self-contained SVG generated from the run's findings — green
247
- `crash-free` or red `N findings`. It's honest because it's *earned*: regenerate it
248
- in CI on every push to `main` and commit it back.
249
-
250
- ```yaml
251
- # .github/workflows/badge.yml — keep the badge honest on every push to main
252
- on:
253
- push:
254
- branches: [main]
255
- jobs:
256
- badge:
257
- runs-on: ubuntu-latest
258
- permissions:
259
- contents: write
260
- steps:
261
- - uses: actions/checkout@v4
262
- - uses: actions/setup-node@v4
263
- with:
264
- node-version: 20
265
- - run: npm ci
266
- - name: Boot dev server
267
- run: |
268
- nohup npm run dev > /tmp/dev.log 2>&1 &
269
- for i in $(seq 1 60); do
270
- curl -sS -o /dev/null http://localhost:3000 && break
271
- sleep 2
272
- done
273
- - name: Generate badge
274
- run: npx --yes aztrx-cli@0.3.0 run http://localhost:3000 --badge badge.svg
275
- - name: Commit badge
276
- run: |
277
- git config user.name "github-actions[bot]"
278
- git config user.email "github-actions[bot]@users.noreply.github.com"
279
- git add badge.svg
280
- git commit -m "chore: update aztrx badge" || echo "no change"
281
- git push
282
- ```
283
-
284
- No `--fail-on` here on purpose: the badge reflects the findings whatever they
285
- are, and the run still exits 0 so the commit step always runs. Swap `push` for a
286
- `schedule` cron if you'd rather regenerate daily than on every push.
287
-
288
- ---
289
-
290
- ## Smart Cloud Router
291
-
292
- `--heal` is backed by a two-tier router: a fast/cheap model generates first, its patch
293
- is gated, compiled, and replayed against the repro, and if the bug still reproduces (or
294
- the patch fails a gate) aztrx falls back to the stronger model and tries again. Most
295
- one-line fixes never pay for the big model. With Anthropic the defaults are
296
- `claude-haiku-4-5` → `claude-sonnet-5`; with any other provider you pick both via
297
- `AZTRX_FAST_MODEL` / `AZTRX_MODEL` (or `--heal-fast-model` / `--heal-model`). When only
298
- one model is set, the router collapses to a single tier.
299
-
300
- ## Security & data flow
301
-
302
- **Local-first by default.** A run never phones home unless you pass an opt-in
303
- flag. By default nothing leaves your machine — no telemetry, no cloud sync, no
304
- LLM call.
305
-
306
- | What | Leaves your machine | When |
307
- | --- | --- | --- |
308
- | `run` (default) | nothing | — |
309
- | `--heal` | redacted file + redacted error/stack, to the LLM API | only with `--heal` + `ANTHROPIC_API_KEY` |
310
- | `--share-data` | a sanitized crash→repro→patch tuple | explicit opt-in |
311
- | `--upload` | sanitized findings + counts | explicit opt-in |
312
-
313
- ### Invariants
314
-
315
- - **Sourcemap containment.** A hostile sourcemap or stack URL can't read outside
316
- your repo: every path is resolved against the repo root and rejected if it
317
- escapes it — including through symlinks. Secret-bearing files (`.env`, `.npmrc`,
318
- private keys) are never read into a report or PR comment.
319
- - **Redaction before the model.** `--heal` redacts common secret patterns (keys,
320
- tokens, credentials) from the file, error, and stack before they're sent; only
321
- the repo-relative path and line/column are visible. Redaction is heuristic — it
322
- is not a substitute for not committing secrets.
323
- - **Isolated sandbox, no commits.** Patches land in a detached `git worktree` in
324
- the OS temp dir — never your working tree. Aztrx AI never commits. A patch must
325
- parse, add no new imports / `eval` / `child_process`, typecheck, *and* pass your
326
- own test suite before it's offered as a `.patch` for you to review.
327
- - **Deny-by-default network.** Only the target origin (plus explicit
328
- `--allow-host`) is reachable; off-origin calls are blocked.
329
- - **Destructive-action deny-list.** Never clicks delete / pay / logout.
330
- - **Studio is localhost-only.** The dashboard binds `127.0.0.1` with no wildcard
331
- CORS.
332
- - **`.aztrx/` is gitignored** on `init` — repro specs, reports, and patches stay
333
- out of history.
334
- - **Pinned supply chain.** The GitHub Action pins `aztrx-cli@0.3.0` (never
335
- `@latest`).
336
-
337
- ## Telemetry & privacy
338
-
339
- Off by default and strictly opt-in. `--telemetry` collects the anonymized tuple
340
- `[crash_fingerprint, min_repro_spec, verified_patch, framework_metadata,
341
- model_tier_used]` locally (nothing leaves the machine); `--share-data` uploads it
342
- to the telemetry endpoint. Every field passes a sanitizer that irreversibly
343
- strips secrets, anonymizes URLs to `<host>`, and scrubs repo paths to `<repo>`.
344
- Uploads are fire-and-forget, bounded by a 2s timeout, and never affect the exit
345
- code.
346
-
347
- ---
348
-
349
- ## Open benchmark
350
-
351
- The detector is scored against a 13-target corpus of **real Next.js App Router
352
- apps** — one seeded runtime bug per app across the archetype matrix (null deref,
353
- async race, JSON parse, stack overflow, Server Action, route transition, and more).
354
-
355
- | metric | value |
356
- | --- | --- |
357
- | seeded bugs | 13 |
358
- | detection recall | **100%** (13 / 13) |
359
- | deterministic repros | **100%** (12 / 12) |
360
- | repro not attempted | 1 (mount-time bug, no action history) |
361
- | unseeded findings | 5 — two root causes (`/api/cart` → 500, Server Action → 500) |
362
-
363
- ```bash
364
- cd bench/frameworks
365
- npm install # once — installs next/react for the target apps
366
- npm run bench # detection
367
- npm run bench:repro # detection + repro scoring
368
- ```
369
-
370
- Full per-case table and scoring notes live in
371
- [`bench/frameworks/RESULTS.md`](bench/frameworks/RESULTS.md).
372
-
373
- ---
374
-
375
- ## Architecture
376
-
377
- Aztrx AI is a decoupled, event-driven pipeline — modules talk only through an
378
- `EventBus`; the orchestrator wires them together.
379
-
380
- ```
381
- [ CDP interceptor ] ──▶ [ action ring buffer ] ──▶ [ classifier (fingerprint) ]
382
-
383
- [ verified .patch ] ◀── [ LLM healer ] ◀── [ ddmin minimizer ] ◀── [ sourcemap resolver ]
384
-
385
- [ Playwright spec (.spec.ts) ] ──▶ [ flake-rate validator ]
386
- ```
387
-
388
- | Stage | Module | Role |
389
- | --- | --- | --- |
390
- | F1 | `interceptor.ts` | CDP interceptor — captures raw runtime errors and console/network events |
391
- | F2 | `recorder.ts` | Ring buffer of the last 25 actions; selector cascade `data-testid → text → CSS path` |
392
- | F3 | `classifier.ts` | Fingerprints + dedups findings, assigns severity; suppresses `.aztrx/baseline.json` (input) |
393
- | F4 | `resolver.ts` | Maps minified frames to source files, lines, and snippets via sourcemaps |
394
- | F5 | `fuzzer.ts` + `domWalker.ts` | Seeded chaos fuzzer; `domWalker` (F5-lite) discovers interactive elements |
395
- | F6 | `networkGuard.ts` + `domWalker.ts` | Deny-by-default network policy + destructive-action deny-list |
396
- | F7 | `minimizer.ts` | ddmin delta-debugging — eliminates irrelevant actions |
397
- | F8 | `specCompiler.ts` | Emits standalone, clean Playwright `.spec.ts` repro |
398
- | F9 | `validator.ts` | Multi-pass replays → `deterministic` / `flaky` / `unreliable` |
399
- | F10 | `heal/` | Closed-loop healing — redact → generate → AST gate → sandbox → `tsc` → verify |
400
- | F11 | `telemetry/` | Opt-in anonymized crash→repro→patch tuple collection (data flywheel) |
401
- | F12 | `cloud/` | Opt-in cloud sync — streams sanitized findings to the ingest dashboard |
402
- | F13 | `summarize.ts` + `heal/apply.ts` | Human-language "X-ray" report + opt-in apply of verified patches (`--fix`) |
403
-
404
- ---
405
-
406
- ## Roadmap
407
-
408
- - [x] Closed-loop healing — redact → generate → gate → sandbox → verify (F10)
409
- - [ ] Open-source launch — npm publish, `npx aztrx-cli run`, hero screencast
410
- - [x] Hardening — `--auth`/`--storage-state`, tsc compile fast-fail, React 19/Next.js 15 triage
411
- - [x] Real-project benchmark — 13 Next.js App Router targets (100% recall, 100% deterministic repro)
412
- - [x] B2B ($29/mo) — GitHub Action (`action.yml` + reusable workflow), PR bot markdown comment
413
- - [x] B2B ($29/mo) — Smart Cloud Router (haiku fast-tier → verify → Sonnet fallback)
414
- - [x] B2B ($29/mo) — Cloud dashboard (api.aztrx.app)
415
- - [x] Data flywheel — opt-in anonymized patch-tuple collection (F11)
416
- - [x] Server-side healing — heal server `5xx` findings (verify a patch by booting the patched server; requires a leaked server stack + a resolvable start command)
417
- - [x] Human-language "X-ray" report — `--explain` / `--lang` (LLM + offline fallback)
418
- - [x] One-click heal & apply — `--fix` (verified patch → working tree, `y/N`, no commit)
419
- - [x] Autonomous Swarm — parallel detection: walk + multi-seed fuzz + http-fuzz workers, merged by fingerprint
420
- - [x] Auth auto-login — `--login` walks login forms (synthesize test tokens — next)
421
- - [x] Code modernizer — LLM-rewrite legacy JS/TS (`modernize`; Python — next)
422
-
423
193
  ## Contributing
424
194
 
425
195
  ```bash
426
- git clone https://github.com/DanisChaparov/aztrx
196
+ git clone https://github.com/Aztrx-AI/aztrx
427
197
  cd aztrx
428
198
  npm install
429
199
  npx playwright install chromium
@@ -435,10 +205,10 @@ node dist/cli.js http://localhost:8901/crash.html --repo fixtures --repro
435
205
  # → one ● crash mapped to crash.html:13:15, minimized to 1 step
436
206
  ```
437
207
 
438
- ## Support the project
208
+ ## Support
439
209
 
440
- If Aztrx AI saved you hours of debugging or helped you ship a clean release, you
441
- can support the author directly — name a fair price on Polar.sh:
210
+ If Aztrx AI saved you hours of debugging, you can support the author directly
211
+ name a fair price on Polar.sh:
442
212
 
443
213
  **[Donate on Polar.sh →](https://buy.polar.sh/polar_cl_f1vBaxUv3S4fJ0o28GfgzQz7gHDHXkecCQtxY0WqeFs)**
444
214