afterburn-cli 1.0.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/LICENSE +21 -0
- package/README.md +281 -0
- package/dist/ai/gemini-client.d.ts +21 -0
- package/dist/ai/gemini-client.js +105 -0
- package/dist/ai/gemini-client.js.map +1 -0
- package/dist/ai/index.d.ts +1 -0
- package/dist/ai/index.js +3 -0
- package/dist/ai/index.js.map +1 -0
- package/dist/analysis/diagnosis-schema.d.ts +106 -0
- package/dist/analysis/diagnosis-schema.js +54 -0
- package/dist/analysis/diagnosis-schema.js.map +1 -0
- package/dist/analysis/error-analyzer.d.ts +9 -0
- package/dist/analysis/error-analyzer.js +573 -0
- package/dist/analysis/error-analyzer.js.map +1 -0
- package/dist/analysis/index.d.ts +4 -0
- package/dist/analysis/index.js +6 -0
- package/dist/analysis/index.js.map +1 -0
- package/dist/analysis/source-mapper.d.ts +19 -0
- package/dist/analysis/source-mapper.js +329 -0
- package/dist/analysis/source-mapper.js.map +1 -0
- package/dist/analysis/ui-auditor.d.ts +9 -0
- package/dist/analysis/ui-auditor.js +104 -0
- package/dist/analysis/ui-auditor.js.map +1 -0
- package/dist/artifacts/artifact-storage.d.ts +44 -0
- package/dist/artifacts/artifact-storage.js +99 -0
- package/dist/artifacts/artifact-storage.js.map +1 -0
- package/dist/artifacts/index.d.ts +1 -0
- package/dist/artifacts/index.js +3 -0
- package/dist/artifacts/index.js.map +1 -0
- package/dist/browser/browser-manager.d.ts +45 -0
- package/dist/browser/browser-manager.js +88 -0
- package/dist/browser/browser-manager.js.map +1 -0
- package/dist/browser/challenge-detector.d.ts +10 -0
- package/dist/browser/challenge-detector.js +58 -0
- package/dist/browser/challenge-detector.js.map +1 -0
- package/dist/browser/cookie-dismisser.d.ts +18 -0
- package/dist/browser/cookie-dismisser.js +76 -0
- package/dist/browser/cookie-dismisser.js.map +1 -0
- package/dist/browser/index.d.ts +4 -0
- package/dist/browser/index.js +6 -0
- package/dist/browser/index.js.map +1 -0
- package/dist/browser/stealth-browser.d.ts +13 -0
- package/dist/browser/stealth-browser.js +59 -0
- package/dist/browser/stealth-browser.js.map +1 -0
- package/dist/cli/commander-cli.d.ts +2 -0
- package/dist/cli/commander-cli.js +150 -0
- package/dist/cli/commander-cli.js.map +1 -0
- package/dist/cli/doctor.d.ts +34 -0
- package/dist/cli/doctor.js +124 -0
- package/dist/cli/doctor.js.map +1 -0
- package/dist/cli/first-run.d.ts +6 -0
- package/dist/cli/first-run.js +58 -0
- package/dist/cli/first-run.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.js +5 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/progress.d.ts +11 -0
- package/dist/cli/progress.js +30 -0
- package/dist/cli/progress.js.map +1 -0
- package/dist/core/engine.d.ts +33 -0
- package/dist/core/engine.js +269 -0
- package/dist/core/engine.js.map +1 -0
- package/dist/core/index.d.ts +3 -0
- package/dist/core/index.js +4 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/validation.d.ts +52 -0
- package/dist/core/validation.js +228 -0
- package/dist/core/validation.js.map +1 -0
- package/dist/discovery/crawler.d.ts +58 -0
- package/dist/discovery/crawler.js +240 -0
- package/dist/discovery/crawler.js.map +1 -0
- package/dist/discovery/discovery-pipeline.d.ts +22 -0
- package/dist/discovery/discovery-pipeline.js +256 -0
- package/dist/discovery/discovery-pipeline.js.map +1 -0
- package/dist/discovery/element-mapper.d.ts +21 -0
- package/dist/discovery/element-mapper.js +422 -0
- package/dist/discovery/element-mapper.js.map +1 -0
- package/dist/discovery/index.d.ts +8 -0
- package/dist/discovery/index.js +8 -0
- package/dist/discovery/index.js.map +1 -0
- package/dist/discovery/link-validator.d.ts +15 -0
- package/dist/discovery/link-validator.js +137 -0
- package/dist/discovery/link-validator.js.map +1 -0
- package/dist/discovery/sitemap-builder.d.ts +19 -0
- package/dist/discovery/sitemap-builder.js +166 -0
- package/dist/discovery/sitemap-builder.js.map +1 -0
- package/dist/discovery/spa-detector.d.ts +12 -0
- package/dist/discovery/spa-detector.js +271 -0
- package/dist/discovery/spa-detector.js.map +1 -0
- package/dist/execution/error-detector.d.ts +10 -0
- package/dist/execution/error-detector.js +87 -0
- package/dist/execution/error-detector.js.map +1 -0
- package/dist/execution/evidence-capture.d.ts +8 -0
- package/dist/execution/evidence-capture.js +37 -0
- package/dist/execution/evidence-capture.js.map +1 -0
- package/dist/execution/index.d.ts +5 -0
- package/dist/execution/index.js +7 -0
- package/dist/execution/index.js.map +1 -0
- package/dist/execution/step-handlers.d.ts +48 -0
- package/dist/execution/step-handlers.js +349 -0
- package/dist/execution/step-handlers.js.map +1 -0
- package/dist/execution/test-data.d.ts +50 -0
- package/dist/execution/test-data.js +160 -0
- package/dist/execution/test-data.js.map +1 -0
- package/dist/execution/workflow-executor.d.ts +56 -0
- package/dist/execution/workflow-executor.js +331 -0
- package/dist/execution/workflow-executor.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/entry.d.ts +2 -0
- package/dist/mcp/entry.js +5 -0
- package/dist/mcp/entry.js.map +1 -0
- package/dist/mcp/index.d.ts +2 -0
- package/dist/mcp/index.js +4 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/server.d.ts +3 -0
- package/dist/mcp/server.js +19 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/tools.d.ts +2 -0
- package/dist/mcp/tools.js +162 -0
- package/dist/mcp/tools.js.map +1 -0
- package/dist/planning/heuristic-planner.d.ts +7 -0
- package/dist/planning/heuristic-planner.js +238 -0
- package/dist/planning/heuristic-planner.js.map +1 -0
- package/dist/planning/index.d.ts +3 -0
- package/dist/planning/index.js +5 -0
- package/dist/planning/index.js.map +1 -0
- package/dist/planning/plan-schema.d.ts +74 -0
- package/dist/planning/plan-schema.js +39 -0
- package/dist/planning/plan-schema.js.map +1 -0
- package/dist/planning/workflow-planner.d.ts +39 -0
- package/dist/planning/workflow-planner.js +211 -0
- package/dist/planning/workflow-planner.js.map +1 -0
- package/dist/reports/health-scorer.d.ts +14 -0
- package/dist/reports/health-scorer.js +88 -0
- package/dist/reports/health-scorer.js.map +1 -0
- package/dist/reports/html-generator.d.ts +10 -0
- package/dist/reports/html-generator.js +155 -0
- package/dist/reports/html-generator.js.map +1 -0
- package/dist/reports/index.d.ts +4 -0
- package/dist/reports/index.js +6 -0
- package/dist/reports/index.js.map +1 -0
- package/dist/reports/markdown-generator.d.ts +10 -0
- package/dist/reports/markdown-generator.js +334 -0
- package/dist/reports/markdown-generator.js.map +1 -0
- package/dist/reports/priority-ranker.d.ts +22 -0
- package/dist/reports/priority-ranker.js +608 -0
- package/dist/reports/priority-ranker.js.map +1 -0
- package/dist/screenshots/dual-format.d.ts +14 -0
- package/dist/screenshots/dual-format.js +59 -0
- package/dist/screenshots/dual-format.js.map +1 -0
- package/dist/screenshots/index.d.ts +2 -0
- package/dist/screenshots/index.js +4 -0
- package/dist/screenshots/index.js.map +1 -0
- package/dist/screenshots/screenshot-manager.d.ts +33 -0
- package/dist/screenshots/screenshot-manager.js +86 -0
- package/dist/screenshots/screenshot-manager.js.map +1 -0
- package/dist/testing/accessibility-auditor.d.ts +23 -0
- package/dist/testing/accessibility-auditor.js +44 -0
- package/dist/testing/accessibility-auditor.js.map +1 -0
- package/dist/testing/index.d.ts +4 -0
- package/dist/testing/index.js +5 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/testing/meta-auditor.d.ts +16 -0
- package/dist/testing/meta-auditor.js +268 -0
- package/dist/testing/meta-auditor.js.map +1 -0
- package/dist/testing/performance-monitor.d.ts +15 -0
- package/dist/testing/performance-monitor.js +64 -0
- package/dist/testing/performance-monitor.js.map +1 -0
- package/dist/types/artifacts.d.ts +58 -0
- package/dist/types/artifacts.js +3 -0
- package/dist/types/artifacts.js.map +1 -0
- package/dist/types/discovery.d.ts +124 -0
- package/dist/types/discovery.js +3 -0
- package/dist/types/discovery.js.map +1 -0
- package/dist/types/execution.d.ts +154 -0
- package/dist/types/execution.js +3 -0
- package/dist/types/execution.js.map +1 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.js +4 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/sanitizer.d.ts +25 -0
- package/dist/utils/sanitizer.js +98 -0
- package/dist/utils/sanitizer.js.map +1 -0
- package/package.json +86 -0
- package/templates/report.hbs +202 -0
- package/templates/styles/report.css +607 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Afterburn Contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
# Afterburn
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/afterburn-cli)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
[](https://nodejs.org/)
|
|
6
|
+
[]()
|
|
7
|
+
[]()
|
|
8
|
+
|
|
9
|
+
**One command finds every bug on your website.** Zero config. Generates a report your AI coding tool can use to fix them automatically.
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npx afterburn-cli https://your-site.com
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
Afterburn v1.0.0
|
|
17
|
+
|
|
18
|
+
✔ Checking browser...
|
|
19
|
+
✔ Crawling site...
|
|
20
|
+
✔ Testing workflows...
|
|
21
|
+
✔ Analyzing results...
|
|
22
|
+
✔ Generating reports...
|
|
23
|
+
|
|
24
|
+
Health: 62/100 — 20 issues found (0 high, 17 medium, 3 low)
|
|
25
|
+
|
|
26
|
+
Reports saved:
|
|
27
|
+
HTML: afterburn-reports/1770564079516/report.html
|
|
28
|
+
Markdown: afterburn-reports/1770564079516/report.md
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Afterburn crawls your site, fills out forms, clicks every button, and tells you what's broken -- in plain English for you, in structured Markdown for Claude, Cursor, or ChatGPT to auto-fix.
|
|
32
|
+
|
|
33
|
+
> **The AI workflow:** Afterburn finds the bugs. You paste the Markdown report into Claude, Cursor, or ChatGPT. It reads the reproduction steps and fixes them. You re-scan. Done.
|
|
34
|
+
|
|
35
|
+
## The AI-readable report (the killer feature)
|
|
36
|
+
|
|
37
|
+
Every scan generates **two reports**:
|
|
38
|
+
|
|
39
|
+
1. **HTML Report** -- A health score and prioritized bug list in plain English. For you to read.
|
|
40
|
+
2. **Markdown Report** -- Structured with reproduction steps and fix suggestions. Feed it directly to Claude, ChatGPT, or Cursor and your AI coding tool can **fix the bugs automatically**.
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
You: "Here's my Afterburn report. Fix these bugs."
|
|
44
|
+
AI: *reads structured report, fixes 12 issues across 4 files*
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
This is the workflow: Afterburn finds the bugs, your AI fixes them. Zero manual debugging.
|
|
48
|
+
|
|
49
|
+
### What the AI report looks like
|
|
50
|
+
|
|
51
|
+
The Markdown report is structured so AI tools can parse and act on it:
|
|
52
|
+
|
|
53
|
+
```markdown
|
|
54
|
+
## Issues (Prioritized)
|
|
55
|
+
|
|
56
|
+
| # | Priority | Category | Summary | Location |
|
|
57
|
+
|---|----------|----------|---------|----------|
|
|
58
|
+
| 1 | HIGH | Workflow Error | Form "form#contact-form" submission isn't working | /contact |
|
|
59
|
+
| 2 | MEDIUM | Dead Button | Button "Get Started Free" doesn't do anything when clicked | / |
|
|
60
|
+
| 3 | MEDIUM | Console Error | An image failed to load | /images/icon-deploy.png |
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Each issue includes a category, priority, plain-English summary, and location. Paste this into Claude or Cursor and it knows exactly what to fix.
|
|
64
|
+
|
|
65
|
+
### Sample reports
|
|
66
|
+
|
|
67
|
+
See what Afterburn produces when scanning a real app with 20+ intentional defects:
|
|
68
|
+
|
|
69
|
+

|
|
70
|
+
|
|
71
|
+
- [Sample HTML report](demo-cache/report.html) -- Health score, prioritized issues, fix suggestions
|
|
72
|
+
- [Sample Markdown report](demo-cache/report.md) -- Structured for AI coding tools
|
|
73
|
+
- [Terminal output](demo-cache/terminal-output.txt) -- What you see in the CLI
|
|
74
|
+
|
|
75
|
+
## What it catches
|
|
76
|
+
|
|
77
|
+
- Broken forms that don't submit
|
|
78
|
+
- Dead buttons that do nothing when clicked
|
|
79
|
+
- JavaScript errors and console crashes
|
|
80
|
+
- HTTP errors (404s, 500s, failed API calls)
|
|
81
|
+
- Broken images and missing assets
|
|
82
|
+
- Accessibility violations (WCAG 2.1 AA via axe-core)
|
|
83
|
+
- Slow page loads and poor performance scores
|
|
84
|
+
|
|
85
|
+
## Quick start
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
# No install needed -- run directly
|
|
89
|
+
npx afterburn-cli https://your-site.com
|
|
90
|
+
|
|
91
|
+
# Or install globally
|
|
92
|
+
npm install -g afterburn-cli
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Afterburn downloads a browser automatically on first run (~200MB, one-time).
|
|
96
|
+
|
|
97
|
+
## Try it now
|
|
98
|
+
|
|
99
|
+
Scan any public website -- no signup, no API key, no config:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
npx afterburn-cli https://en.wikipedia.org/wiki/Main_Page
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Or point it at your own site to see what's broken.
|
|
106
|
+
|
|
107
|
+
### Common options
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
# Test login flows
|
|
111
|
+
npx afterburn-cli https://your-site.com --email test@example.com --password mypass123
|
|
112
|
+
|
|
113
|
+
# Hint at specific workflows
|
|
114
|
+
npx afterburn-cli https://your-site.com --flows "signup, checkout, profile edit"
|
|
115
|
+
|
|
116
|
+
# Map bugs to your source code (file:line)
|
|
117
|
+
npx afterburn-cli https://your-site.com --source ./src
|
|
118
|
+
|
|
119
|
+
# Watch the browser do its thing
|
|
120
|
+
npx afterburn-cli https://your-site.com --no-headless
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Reports are saved to `./afterburn-reports/{timestamp}/`.
|
|
124
|
+
|
|
125
|
+
## How it works
|
|
126
|
+
|
|
127
|
+
```
|
|
128
|
+
Your URL --> Crawl all pages --> Plan test workflows --> Execute tests --> Analyze failures --> Generate reports
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
1. **Crawl** -- Discovers all pages, forms, buttons, and links. Handles SPAs (React, Next.js, Vue, Angular, Svelte).
|
|
132
|
+
2. **Plan** -- AI generates smart test workflows (or heuristic fallback with no API key).
|
|
133
|
+
3. **Execute** -- Runs each workflow in a real browser: fills forms, clicks buttons, captures screenshots.
|
|
134
|
+
4. **Analyze** -- Diagnoses root causes. AI vision analysis with Gemini, or pattern matching without.
|
|
135
|
+
5. **Report** -- Health score (0-100) and prioritized fix list in HTML + Markdown.
|
|
136
|
+
|
|
137
|
+
### AI is optional
|
|
138
|
+
|
|
139
|
+
Afterburn works **without any API keys**. Set `GEMINI_API_KEY` for smarter test planning and AI-powered diagnosis, but the core tool runs a full test suite either way.
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
# Optional: enable AI-powered planning and diagnosis
|
|
143
|
+
export GEMINI_API_KEY=your-key-here
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
## How is this different?
|
|
147
|
+
|
|
148
|
+
| Feature | Afterburn | Lighthouse | axe-core | Manual testing |
|
|
149
|
+
|---------|-----------|------------|----------|----------------|
|
|
150
|
+
| Zero config (no test writing) | Yes | Yes | Needs integration | Yes |
|
|
151
|
+
| Crawls entire site | Yes | Single page | No | Tedious |
|
|
152
|
+
| Form filling and submission | Yes | No | No | Manual |
|
|
153
|
+
| Dead button detection | Yes | No | No | If you notice |
|
|
154
|
+
| Plain English reports | Yes | Partial | No | N/A |
|
|
155
|
+
| AI-ready report for auto-fix | Yes | No | No | No |
|
|
156
|
+
| Free and open source | Yes | Yes | Yes | Free (your time) |
|
|
157
|
+
| CI/CD integration | GitHub Action | CI plugin | CI plugin | No |
|
|
158
|
+
|
|
159
|
+
## Health score
|
|
160
|
+
|
|
161
|
+
The health score (0-100) is weighted:
|
|
162
|
+
|
|
163
|
+
| Category | Weight | What it measures |
|
|
164
|
+
|----------|--------|------------------|
|
|
165
|
+
| Workflows | 40% | Did test workflows complete without errors? |
|
|
166
|
+
| Errors | 30% | HTTP errors, console crashes, broken resources |
|
|
167
|
+
| Accessibility | 20% | WCAG 2.1 AA violations |
|
|
168
|
+
| Performance | 10% | Page load times, LCP scores |
|
|
169
|
+
|
|
170
|
+
## Pre-flight check
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
npx afterburn-cli doctor
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
Checks Node.js version, browser installation, API key, and network connectivity.
|
|
177
|
+
|
|
178
|
+
## Testing
|
|
179
|
+
|
|
180
|
+
```bash
|
|
181
|
+
# Build CLI + bundled GitHub Action artifacts
|
|
182
|
+
npm run build:release
|
|
183
|
+
|
|
184
|
+
# Fast default lane (unit tests)
|
|
185
|
+
npm test
|
|
186
|
+
|
|
187
|
+
# Deterministic end-to-end lane (local fixture server)
|
|
188
|
+
npm run test:e2e
|
|
189
|
+
|
|
190
|
+
# Unit coverage gate with thresholds
|
|
191
|
+
npm run test:coverage
|
|
192
|
+
|
|
193
|
+
# Optional real-internet smoke test (only runs when URL is provided)
|
|
194
|
+
AFTERBURN_EXTERNAL_SMOKE_URL=https://example.com npm run test:smoke:external
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
## CLI reference
|
|
198
|
+
|
|
199
|
+
```
|
|
200
|
+
Usage: afterburn [options] [command] <url>
|
|
201
|
+
|
|
202
|
+
Automated testing for vibe-coded websites
|
|
203
|
+
|
|
204
|
+
Arguments:
|
|
205
|
+
url URL to test
|
|
206
|
+
|
|
207
|
+
Options:
|
|
208
|
+
-V, --version output the version number
|
|
209
|
+
--source <path> Source code directory for pinpointing bugs
|
|
210
|
+
--email <email> Login email (or set AFTERBURN_EMAIL env var)
|
|
211
|
+
--password <password> Login password (tip: use AFTERBURN_PASSWORD env var
|
|
212
|
+
to avoid shell history exposure)
|
|
213
|
+
--output-dir <path> Custom output directory
|
|
214
|
+
(default: ./afterburn-reports/{timestamp})
|
|
215
|
+
--flows <hints> Comma-separated workflow hints (e.g., "signup, checkout")
|
|
216
|
+
--max-pages <n> Max pages to crawl (default: 50, max: 500)
|
|
217
|
+
--no-headless Show browser window (useful for debugging)
|
|
218
|
+
--verbose Show detailed progress output
|
|
219
|
+
-h, --help display help for command
|
|
220
|
+
|
|
221
|
+
Commands:
|
|
222
|
+
doctor Check if your environment is ready to run Afterburn
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
## Known limitations
|
|
226
|
+
|
|
227
|
+
- **Visual analysis requires GEMINI_API_KEY**. Without it, UI analysis relies on axe-core plus pattern matching.
|
|
228
|
+
- **SPA support is experimental**. Complex client-side routing may not be fully exercised.
|
|
229
|
+
- **Desktop viewport only**. Tests run at 1920x1080. Mobile testing planned for v2.
|
|
230
|
+
|
|
231
|
+
## Three interfaces
|
|
232
|
+
|
|
233
|
+
### CLI
|
|
234
|
+
|
|
235
|
+
```bash
|
|
236
|
+
npx afterburn-cli https://your-site.com
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
### GitHub Action
|
|
240
|
+
|
|
241
|
+
```yaml
|
|
242
|
+
name: Afterburn
|
|
243
|
+
on: [pull_request]
|
|
244
|
+
|
|
245
|
+
jobs:
|
|
246
|
+
test:
|
|
247
|
+
runs-on: ubuntu-latest
|
|
248
|
+
steps:
|
|
249
|
+
- uses: actions/checkout@v4
|
|
250
|
+
- uses: gods-strongest-vibecoder/afterburn@main
|
|
251
|
+
with:
|
|
252
|
+
url: https://your-staging-site.com
|
|
253
|
+
fail-on: high
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
Posts a summary comment on your PR and uploads reports as artifacts.
|
|
257
|
+
|
|
258
|
+
### MCP Server (for AI coding assistants)
|
|
259
|
+
|
|
260
|
+
```json
|
|
261
|
+
{
|
|
262
|
+
"mcpServers": {
|
|
263
|
+
"afterburn": {
|
|
264
|
+
"command": "npx",
|
|
265
|
+
"args": ["afterburn-mcp"]
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
Exposes a `scan_website` tool that returns structured results your AI assistant can act on.
|
|
272
|
+
|
|
273
|
+
## Tech stack
|
|
274
|
+
|
|
275
|
+
[Playwright](https://playwright.dev/) (browser automation) | [Gemini 2.5 Flash](https://ai.google.dev/) (AI vision, optional) | [axe-core](https://github.com/dequelabs/axe-core) (accessibility) | [Commander.js](https://github.com/tj/commander.js) (CLI) | [Handlebars](https://handlebarsjs.com/) (HTML reports) | [ts-morph](https://github.com/dsherret/ts-morph) (source mapping) | [sharp](https://sharp.pixelplumbing.com/) (screenshot compression)
|
|
276
|
+
|
|
277
|
+
## License
|
|
278
|
+
|
|
279
|
+
MIT
|
|
280
|
+
|
|
281
|
+
Built for the [BridgeMind Vibeathon 2026](https://bridgemind.dev).
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* Reusable Gemini 2.5 Flash client for structured and unstructured generation.
|
|
4
|
+
* Used for workflow planning (Phase 2), error diagnosis (Phase 4), and report generation (Phase 5).
|
|
5
|
+
*/
|
|
6
|
+
export declare class GeminiClient {
|
|
7
|
+
private model;
|
|
8
|
+
constructor(apiKey?: string);
|
|
9
|
+
/**
|
|
10
|
+
* Generate structured JSON output validated against a Zod schema
|
|
11
|
+
*/
|
|
12
|
+
generateStructured<T>(prompt: string, schema: z.ZodType<T>): Promise<T>;
|
|
13
|
+
/**
|
|
14
|
+
* Generate plain text response (no schema constraints)
|
|
15
|
+
*/
|
|
16
|
+
generateText(prompt: string): Promise<string>;
|
|
17
|
+
/**
|
|
18
|
+
* Generate structured JSON output with image input (multimodal)
|
|
19
|
+
*/
|
|
20
|
+
generateStructuredWithImage<T>(prompt: string, schema: z.ZodType<T>, imagePath: string): Promise<T>;
|
|
21
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
// Gemini 2.5 Flash API client with structured JSON output support
|
|
2
|
+
import { GoogleGenerativeAI } from '@google/generative-ai';
|
|
3
|
+
import { zodToJsonSchema } from 'zod-to-json-schema';
|
|
4
|
+
import fs from 'node:fs';
|
|
5
|
+
/**
|
|
6
|
+
* Reusable Gemini 2.5 Flash client for structured and unstructured generation.
|
|
7
|
+
* Used for workflow planning (Phase 2), error diagnosis (Phase 4), and report generation (Phase 5).
|
|
8
|
+
*/
|
|
9
|
+
export class GeminiClient {
|
|
10
|
+
model;
|
|
11
|
+
constructor(apiKey) {
|
|
12
|
+
const key = apiKey || process.env.GEMINI_API_KEY;
|
|
13
|
+
if (!key) {
|
|
14
|
+
throw new Error('GEMINI_API_KEY not set. Get one at https://aistudio.google.com/apikey');
|
|
15
|
+
}
|
|
16
|
+
const genAI = new GoogleGenerativeAI(key);
|
|
17
|
+
this.model = genAI.getGenerativeModel({ model: 'gemini-2.5-flash' });
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Generate structured JSON output validated against a Zod schema
|
|
21
|
+
*/
|
|
22
|
+
async generateStructured(prompt, schema) {
|
|
23
|
+
try {
|
|
24
|
+
// Convert Zod schema to JSON Schema for Gemini
|
|
25
|
+
const jsonSchema = zodToJsonSchema(schema, { name: 'ResponseSchema' });
|
|
26
|
+
// Configure model for structured JSON output
|
|
27
|
+
const result = await this.model.generateContent({
|
|
28
|
+
contents: [{ role: 'user', parts: [{ text: prompt }] }],
|
|
29
|
+
generationConfig: {
|
|
30
|
+
responseMimeType: 'application/json',
|
|
31
|
+
responseSchema: jsonSchema,
|
|
32
|
+
},
|
|
33
|
+
});
|
|
34
|
+
// Extract text response
|
|
35
|
+
const responseText = result.response.text();
|
|
36
|
+
// Parse JSON
|
|
37
|
+
const jsonData = JSON.parse(responseText);
|
|
38
|
+
// Validate against Zod schema
|
|
39
|
+
const validated = schema.parse(jsonData);
|
|
40
|
+
return validated;
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
if (error instanceof Error) {
|
|
44
|
+
throw new Error(`Gemini API error: ${error.message}`);
|
|
45
|
+
}
|
|
46
|
+
throw error;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Generate plain text response (no schema constraints)
|
|
51
|
+
*/
|
|
52
|
+
async generateText(prompt) {
|
|
53
|
+
try {
|
|
54
|
+
const result = await this.model.generateContent(prompt);
|
|
55
|
+
return result.response.text();
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
if (error instanceof Error) {
|
|
59
|
+
throw new Error(`Gemini API error: ${error.message}`);
|
|
60
|
+
}
|
|
61
|
+
throw error;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Generate structured JSON output with image input (multimodal)
|
|
66
|
+
*/
|
|
67
|
+
async generateStructuredWithImage(prompt, schema, imagePath) {
|
|
68
|
+
try {
|
|
69
|
+
// Read image file as base64
|
|
70
|
+
const base64Data = fs.readFileSync(imagePath, { encoding: 'base64' });
|
|
71
|
+
// Convert Zod schema to JSON Schema for Gemini
|
|
72
|
+
const jsonSchema = zodToJsonSchema(schema, { name: 'ResponseSchema' });
|
|
73
|
+
// Configure model for structured JSON output with image
|
|
74
|
+
const result = await this.model.generateContent({
|
|
75
|
+
contents: [
|
|
76
|
+
{
|
|
77
|
+
role: 'user',
|
|
78
|
+
parts: [
|
|
79
|
+
{ text: prompt },
|
|
80
|
+
{ inlineData: { mimeType: 'image/png', data: base64Data } },
|
|
81
|
+
],
|
|
82
|
+
},
|
|
83
|
+
],
|
|
84
|
+
generationConfig: {
|
|
85
|
+
responseMimeType: 'application/json',
|
|
86
|
+
responseSchema: jsonSchema,
|
|
87
|
+
},
|
|
88
|
+
});
|
|
89
|
+
// Extract text response
|
|
90
|
+
const responseText = result.response.text();
|
|
91
|
+
// Parse JSON
|
|
92
|
+
const jsonData = JSON.parse(responseText);
|
|
93
|
+
// Validate against Zod schema
|
|
94
|
+
const validated = schema.parse(jsonData);
|
|
95
|
+
return validated;
|
|
96
|
+
}
|
|
97
|
+
catch (error) {
|
|
98
|
+
if (error instanceof Error) {
|
|
99
|
+
throw new Error(`Gemini API error: ${error.message}`);
|
|
100
|
+
}
|
|
101
|
+
throw error;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=gemini-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gemini-client.js","sourceRoot":"","sources":["../../src/ai/gemini-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { GeminiClient } from './gemini-client.js';
|
package/dist/ai/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/ai/index.ts"],"names":[],"mappings":"AAAA,2BAA2B;AAE3B,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { ArtifactMetadata } from '../types/artifacts.js';
|
|
3
|
+
/**
|
|
4
|
+
* Individual error diagnosis from LLM or fallback pattern matching
|
|
5
|
+
*/
|
|
6
|
+
export declare const ErrorDiagnosisSchema: z.ZodObject<{
|
|
7
|
+
summary: z.ZodString;
|
|
8
|
+
rootCause: z.ZodString;
|
|
9
|
+
errorType: z.ZodEnum<{
|
|
10
|
+
form: "form";
|
|
11
|
+
navigation: "navigation";
|
|
12
|
+
unknown: "unknown";
|
|
13
|
+
authentication: "authentication";
|
|
14
|
+
network: "network";
|
|
15
|
+
javascript: "javascript";
|
|
16
|
+
dom: "dom";
|
|
17
|
+
}>;
|
|
18
|
+
confidence: z.ZodEnum<{
|
|
19
|
+
high: "high";
|
|
20
|
+
medium: "medium";
|
|
21
|
+
low: "low";
|
|
22
|
+
}>;
|
|
23
|
+
suggestedFix: z.ZodString;
|
|
24
|
+
technicalDetails: z.ZodOptional<z.ZodString>;
|
|
25
|
+
}, z.core.$strip>;
|
|
26
|
+
export type ErrorDiagnosis = z.infer<typeof ErrorDiagnosisSchema>;
|
|
27
|
+
/**
|
|
28
|
+
* Batch response schema for diagnosing multiple errors in a single LLM call
|
|
29
|
+
*/
|
|
30
|
+
export declare const ErrorDiagnosisBatchSchema: z.ZodObject<{
|
|
31
|
+
diagnoses: z.ZodArray<z.ZodObject<{
|
|
32
|
+
rootCause: z.ZodString;
|
|
33
|
+
plainEnglish: z.ZodString;
|
|
34
|
+
suggestedFix: z.ZodString;
|
|
35
|
+
severity: z.ZodEnum<{
|
|
36
|
+
high: "high";
|
|
37
|
+
medium: "medium";
|
|
38
|
+
low: "low";
|
|
39
|
+
}>;
|
|
40
|
+
}, z.core.$strip>>;
|
|
41
|
+
}, z.core.$strip>;
|
|
42
|
+
export type ErrorDiagnosisBatch = z.infer<typeof ErrorDiagnosisBatchSchema>;
|
|
43
|
+
/**
|
|
44
|
+
* UI audit findings from vision LLM analysis
|
|
45
|
+
*/
|
|
46
|
+
export declare const UIAuditSchema: z.ZodObject<{
|
|
47
|
+
layoutIssues: z.ZodArray<z.ZodObject<{
|
|
48
|
+
description: z.ZodString;
|
|
49
|
+
severity: z.ZodEnum<{
|
|
50
|
+
high: "high";
|
|
51
|
+
medium: "medium";
|
|
52
|
+
low: "low";
|
|
53
|
+
}>;
|
|
54
|
+
location: z.ZodString;
|
|
55
|
+
}, z.core.$strip>>;
|
|
56
|
+
contrastIssues: z.ZodArray<z.ZodObject<{
|
|
57
|
+
element: z.ZodString;
|
|
58
|
+
issue: z.ZodString;
|
|
59
|
+
suggestion: z.ZodString;
|
|
60
|
+
}, z.core.$strip>>;
|
|
61
|
+
formattingIssues: z.ZodArray<z.ZodObject<{
|
|
62
|
+
problem: z.ZodString;
|
|
63
|
+
suggestion: z.ZodString;
|
|
64
|
+
}, z.core.$strip>>;
|
|
65
|
+
improvements: z.ZodArray<z.ZodString>;
|
|
66
|
+
overallScore: z.ZodEnum<{
|
|
67
|
+
good: "good";
|
|
68
|
+
"needs-work": "needs-work";
|
|
69
|
+
poor: "poor";
|
|
70
|
+
}>;
|
|
71
|
+
}, z.core.$strip>;
|
|
72
|
+
export type UIAudit = z.infer<typeof UIAuditSchema>;
|
|
73
|
+
/**
|
|
74
|
+
* Source code location for an error (populated by source mapper in Plan 04-03)
|
|
75
|
+
*/
|
|
76
|
+
export declare const SourceLocationSchema: z.ZodObject<{
|
|
77
|
+
file: z.ZodString;
|
|
78
|
+
line: z.ZodNumber;
|
|
79
|
+
context: z.ZodString;
|
|
80
|
+
}, z.core.$strip>;
|
|
81
|
+
export type SourceLocation = z.infer<typeof SourceLocationSchema>;
|
|
82
|
+
/**
|
|
83
|
+
* Diagnosed error with original message for source mapping
|
|
84
|
+
*/
|
|
85
|
+
export interface DiagnosedError extends ErrorDiagnosis {
|
|
86
|
+
originalError: string;
|
|
87
|
+
sourceLocation?: SourceLocation;
|
|
88
|
+
screenshotRef?: string;
|
|
89
|
+
pageUrl?: string;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* UI audit result for a specific page
|
|
93
|
+
*/
|
|
94
|
+
export interface UIAuditResult extends UIAudit {
|
|
95
|
+
pageUrl: string;
|
|
96
|
+
screenshotRef?: string;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Complete analysis artifact (output of Phase 4)
|
|
100
|
+
*/
|
|
101
|
+
export interface AnalysisArtifact extends ArtifactMetadata {
|
|
102
|
+
diagnosedErrors: DiagnosedError[];
|
|
103
|
+
uiAudits: UIAuditResult[];
|
|
104
|
+
sourceAnalysisAvailable: boolean;
|
|
105
|
+
aiPowered: boolean;
|
|
106
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
// Zod schemas for Phase 4 error diagnosis, UI auditing, and analysis artifacts
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
/**
|
|
4
|
+
* Individual error diagnosis from LLM or fallback pattern matching
|
|
5
|
+
*/
|
|
6
|
+
export const ErrorDiagnosisSchema = z.object({
|
|
7
|
+
summary: z.string().describe('One-sentence plain English summary of what went wrong'),
|
|
8
|
+
rootCause: z.string().describe('Plain English explanation of the root cause'),
|
|
9
|
+
errorType: z.enum(['network', 'javascript', 'dom', 'form', 'navigation', 'authentication', 'unknown']),
|
|
10
|
+
confidence: z.enum(['high', 'medium', 'low']),
|
|
11
|
+
suggestedFix: z.string().describe('Actionable next step in plain English'),
|
|
12
|
+
technicalDetails: z.string().optional().describe('Technical details for developers'),
|
|
13
|
+
});
|
|
14
|
+
/**
|
|
15
|
+
* Batch response schema for diagnosing multiple errors in a single LLM call
|
|
16
|
+
*/
|
|
17
|
+
export const ErrorDiagnosisBatchSchema = z.object({
|
|
18
|
+
diagnoses: z.array(z.object({
|
|
19
|
+
rootCause: z.string().describe('Plain English explanation of the root cause'),
|
|
20
|
+
plainEnglish: z.string().describe('One-sentence plain English summary of what went wrong'),
|
|
21
|
+
suggestedFix: z.string().describe('Actionable next step in plain English'),
|
|
22
|
+
severity: z.enum(['high', 'medium', 'low']).describe('Severity of the error'),
|
|
23
|
+
})).describe('One diagnosis per error, in the same order as the input errors'),
|
|
24
|
+
});
|
|
25
|
+
/**
|
|
26
|
+
* UI audit findings from vision LLM analysis
|
|
27
|
+
*/
|
|
28
|
+
export const UIAuditSchema = z.object({
|
|
29
|
+
layoutIssues: z.array(z.object({
|
|
30
|
+
description: z.string(),
|
|
31
|
+
severity: z.enum(['high', 'medium', 'low']),
|
|
32
|
+
location: z.string(),
|
|
33
|
+
})),
|
|
34
|
+
contrastIssues: z.array(z.object({
|
|
35
|
+
element: z.string(),
|
|
36
|
+
issue: z.string(),
|
|
37
|
+
suggestion: z.string(),
|
|
38
|
+
})),
|
|
39
|
+
formattingIssues: z.array(z.object({
|
|
40
|
+
problem: z.string(),
|
|
41
|
+
suggestion: z.string(),
|
|
42
|
+
})),
|
|
43
|
+
improvements: z.array(z.string()).describe('Plain English improvement suggestions'),
|
|
44
|
+
overallScore: z.enum(['good', 'needs-work', 'poor']),
|
|
45
|
+
});
|
|
46
|
+
/**
|
|
47
|
+
* Source code location for an error (populated by source mapper in Plan 04-03)
|
|
48
|
+
*/
|
|
49
|
+
export const SourceLocationSchema = z.object({
|
|
50
|
+
file: z.string(),
|
|
51
|
+
line: z.number(),
|
|
52
|
+
context: z.string().describe('First ~200 chars of relevant code'),
|
|
53
|
+
});
|
|
54
|
+
//# sourceMappingURL=diagnosis-schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diagnosis-schema.js","sourceRoot":"","sources":["../../src/analysis/diagnosis-schema.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ExecutionArtifact } from '../types/execution.js';
|
|
2
|
+
import { DiagnosedError } from './diagnosis-schema.js';
|
|
3
|
+
/**
|
|
4
|
+
* Main export: Analyze all errors from ExecutionArtifact and produce plain English diagnoses
|
|
5
|
+
*/
|
|
6
|
+
export declare function analyzeErrors(artifact: ExecutionArtifact, options?: {
|
|
7
|
+
apiKey?: string;
|
|
8
|
+
aiEnabled?: boolean;
|
|
9
|
+
}): Promise<DiagnosedError[]>;
|