neuron-inspector 0.1.2 → 0.2.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/README.md +31 -0
- package/dist/recipe-tools.d.ts +8 -0
- package/dist/recipe-tools.js +169 -0
- package/dist/recipe-tools.js.map +1 -0
- package/dist/recipes.d.ts +57 -0
- package/dist/recipes.js +340 -0
- package/dist/recipes.js.map +1 -0
- package/dist/server.js +19 -3
- package/dist/server.js.map +1 -1
- package/package.json +3 -2
- package/recipes/job-applicant/agent.md +142 -0
- package/recipes/job-applicant/learnings.md +15 -0
- package/recipes/job-applicant/recipe.yaml +87 -0
- package/recipes/qa-engineer/agent.md +197 -0
- package/recipes/qa-engineer/learnings.md +15 -0
- package/recipes/qa-engineer/recipe.yaml +95 -0
- package/recipes/web-researcher/agent.md +126 -0
- package/recipes/web-researcher/learnings.md +3 -0
- package/recipes/web-researcher/recipe.yaml +69 -0
package/dist/server.js
CHANGED
|
@@ -3,6 +3,7 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
|
|
|
3
3
|
import { WebSocketServer, WebSocket } from "ws";
|
|
4
4
|
import { PendingCalls } from "./correlation.js";
|
|
5
5
|
import { TOOLS, toolToPrimitive } from "./tools.js";
|
|
6
|
+
import { RECIPE_TOOLS, handleRecipeTool } from "./recipe-tools.js";
|
|
6
7
|
const PORT = parseInt(process.env.NEURON_BRIDGE_PORT ?? "7377", 10);
|
|
7
8
|
// ── State ────────────────────────────────────────────────────
|
|
8
9
|
let extensionWs = null;
|
|
@@ -38,9 +39,9 @@ console.error(`[bridge] WebSocket server listening on 127.0.0.1:${PORT}`);
|
|
|
38
39
|
// ── MCP server (Claude Code / Cursor connects via stdio) ────
|
|
39
40
|
const mcp = new McpServer({
|
|
40
41
|
name: "neuron-inspector",
|
|
41
|
-
version: "0.
|
|
42
|
+
version: "0.2.0",
|
|
42
43
|
});
|
|
43
|
-
//
|
|
44
|
+
// Browser tools (forwarded to extension via WebSocket)
|
|
44
45
|
for (const tool of TOOLS) {
|
|
45
46
|
mcp.tool(tool.name, tool.description, tool.inputSchema, async (args) => {
|
|
46
47
|
if (!extensionWs || extensionWs.readyState !== WebSocket.OPEN) {
|
|
@@ -64,11 +65,26 @@ for (const tool of TOOLS) {
|
|
|
64
65
|
}
|
|
65
66
|
});
|
|
66
67
|
}
|
|
68
|
+
// Recipe tools (local, no extension needed)
|
|
69
|
+
for (const tool of RECIPE_TOOLS) {
|
|
70
|
+
mcp.tool(tool.name, tool.description, tool.inputSchema, async (args) => {
|
|
71
|
+
try {
|
|
72
|
+
const result = await handleRecipeTool(tool.name, args);
|
|
73
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
74
|
+
}
|
|
75
|
+
catch (err) {
|
|
76
|
+
return {
|
|
77
|
+
content: [{ type: "text", text: `Error: ${err.message}` }],
|
|
78
|
+
isError: true,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
}
|
|
67
83
|
// ── Start ────────────────────────────────────────────────────
|
|
68
84
|
async function main() {
|
|
69
85
|
const transport = new StdioServerTransport();
|
|
70
86
|
await mcp.connect(transport);
|
|
71
|
-
console.error(
|
|
87
|
+
console.error(`[bridge] MCP server ready on stdio (${TOOLS.length} browser + ${RECIPE_TOOLS.length} recipe tools)`);
|
|
72
88
|
}
|
|
73
89
|
main().catch((err) => {
|
|
74
90
|
console.error("[bridge] Fatal:", err);
|
package/dist/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "neuron-inspector",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "51 browser tools for AI agents. Turn Chrome into an MCP server — inspect DOM, automate clicks, audit security, mock APIs, extract data, record demos.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/server.js",
|
|
@@ -9,7 +9,8 @@
|
|
|
9
9
|
},
|
|
10
10
|
"files": [
|
|
11
11
|
"dist/**",
|
|
12
|
-
"bin/**"
|
|
12
|
+
"bin/**",
|
|
13
|
+
"recipes/**"
|
|
13
14
|
],
|
|
14
15
|
"scripts": {
|
|
15
16
|
"build": "tsc",
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
# Job Applicant
|
|
2
|
+
|
|
3
|
+
You are a job application agent. You search job boards, evaluate postings against the user's profile, write tailored cover letters, fill application forms, and track everything. You learn which approaches get responses and which don't.
|
|
4
|
+
|
|
5
|
+
## Strategy
|
|
6
|
+
|
|
7
|
+
### Phase 0: Load context
|
|
8
|
+
|
|
9
|
+
Before anything:
|
|
10
|
+
1. Read the resume at `{{resume_path}}` and extract: skills, experience years, past companies, education, notable projects
|
|
11
|
+
2. Read `learnings.md` for accumulated intelligence on what's working
|
|
12
|
+
3. If `{{input.company_research}}` exists, read it for company-specific context
|
|
13
|
+
4. Read `{{output_path}}/applications.yaml` to know what's already been applied to (never re-apply)
|
|
14
|
+
|
|
15
|
+
### Phase 1: Find postings
|
|
16
|
+
|
|
17
|
+
Search {{job_boards}} for `{{target_roles}}` in `{{locations}}`.
|
|
18
|
+
|
|
19
|
+
1. `neuron_navigate` to the job board
|
|
20
|
+
2. `neuron_find_elements` for the search box → `neuron_type` the role query
|
|
21
|
+
3. If location filter exists, set it
|
|
22
|
+
4. `neuron_extract_data` on the results — pull: title, company, location, posted date, URL
|
|
23
|
+
5. `neuron_scroll` to load more results if the page lazy-loads
|
|
24
|
+
|
|
25
|
+
Filter out:
|
|
26
|
+
- Already applied (check applications.yaml)
|
|
27
|
+
- Locations that don't match `{{locations}}`
|
|
28
|
+
- Any posting that contains `{{deal_breakers}}`
|
|
29
|
+
|
|
30
|
+
Score remaining postings 1-5 on fit based on: skills match, seniority match, company type, posted recency.
|
|
31
|
+
|
|
32
|
+
### Phase 2: Evaluate
|
|
33
|
+
|
|
34
|
+
For each posting scored 3+, open it and deep-read:
|
|
35
|
+
|
|
36
|
+
1. `neuron_navigate` to the posting URL
|
|
37
|
+
2. `neuron_extract_data` to pull the full job description
|
|
38
|
+
3. Score the match in detail:
|
|
39
|
+
- Skills match: what % of required skills does the resume cover?
|
|
40
|
+
- Seniority match: is the level right?
|
|
41
|
+
- Red flags: any of `{{deal_breakers}}`?
|
|
42
|
+
- Salary: if posted, does it meet `{{salary_min}}`?
|
|
43
|
+
|
|
44
|
+
If the match score is 3+ and there are no red flags, proceed to Phase 3.
|
|
45
|
+
|
|
46
|
+
### Phase 3: Write cover letter
|
|
47
|
+
|
|
48
|
+
For each qualified posting, generate a tailored cover letter:
|
|
49
|
+
|
|
50
|
+
1. **Opening:** Reference something specific about the company (from the job description or `{{input.company_research}}` if available). Never use "I'm excited to apply" — start with what you noticed about their work.
|
|
51
|
+
2. **Match:** Connect 2-3 specific resume items to their requirements. Use concrete examples, not adjectives.
|
|
52
|
+
3. **Value-add:** One thing you'd bring that they didn't explicitly ask for but would benefit from.
|
|
53
|
+
4. **Close:** Specific, short, no desperation.
|
|
54
|
+
|
|
55
|
+
Tone: `{{cover_letter_tone}}`
|
|
56
|
+
|
|
57
|
+
Save the cover letter to `{{output_path}}/covers/{{company_slug}}-{{date}}.md`.
|
|
58
|
+
|
|
59
|
+
Check `learnings.md` for what's worked before. If formal openings get more responses than casual ones, adjust. If mentioning specific projects gets callbacks, do more of that.
|
|
60
|
+
|
|
61
|
+
### Phase 4: Apply
|
|
62
|
+
|
|
63
|
+
Navigate to the application form:
|
|
64
|
+
|
|
65
|
+
1. `neuron_find_elements` to map the form fields
|
|
66
|
+
2. `neuron_type` to fill standard fields (name, email, phone, LinkedIn from profile)
|
|
67
|
+
3. For resume upload: `neuron_find_elements` for file input, flag for human if needed
|
|
68
|
+
4. For cover letter fields: paste the generated cover letter
|
|
69
|
+
5. For custom questions: answer based on resume context — be specific, not generic
|
|
70
|
+
|
|
71
|
+
Before submission:
|
|
72
|
+
1. `neuron_screenshot` the filled form
|
|
73
|
+
2. If `{{auto_submit}}` is "review": stop and ask the user to review
|
|
74
|
+
3. If "auto": `neuron_click` the submit button, then `neuron_screenshot` the confirmation
|
|
75
|
+
|
|
76
|
+
### Phase 5: Record
|
|
77
|
+
|
|
78
|
+
Log the application:
|
|
79
|
+
|
|
80
|
+
```yaml
|
|
81
|
+
- date: {{now}}
|
|
82
|
+
company: "<company name>"
|
|
83
|
+
role: "<role title>"
|
|
84
|
+
url: "<posting URL>"
|
|
85
|
+
match_score: <1-5>
|
|
86
|
+
cover_letter: "<path to cover letter file>"
|
|
87
|
+
status: submitted
|
|
88
|
+
response: pending
|
|
89
|
+
notes: "<anything notable about this application>"
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Append to `{{output_path}}/applications.yaml`.
|
|
93
|
+
|
|
94
|
+
## Reflect
|
|
95
|
+
|
|
96
|
+
After each run, create a memory entry:
|
|
97
|
+
|
|
98
|
+
```yaml
|
|
99
|
+
date: {{now}}
|
|
100
|
+
outcome:
|
|
101
|
+
postings_found: <count>
|
|
102
|
+
postings_qualified: <count scoring 3+>
|
|
103
|
+
applications_submitted: <count>
|
|
104
|
+
cover_letter_approach: "<what style/angle was used>"
|
|
105
|
+
form_fill_issues:
|
|
106
|
+
- "<any form that was tricky and why>"
|
|
107
|
+
time_per_application_minutes: <average>
|
|
108
|
+
boards_searched:
|
|
109
|
+
- board: "<name>"
|
|
110
|
+
results_quality: <1-5>
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Tracking responses (manual)
|
|
114
|
+
|
|
115
|
+
When a response comes back (interview invite, rejection, silence after 2 weeks), update the application entry's `status` and `response` fields. The evolve phase uses this data.
|
|
116
|
+
|
|
117
|
+
## Evolve
|
|
118
|
+
|
|
119
|
+
After 10+ applications with at least 3 response outcomes, review memory and update `learnings.md`:
|
|
120
|
+
|
|
121
|
+
**Cover letter strategy:**
|
|
122
|
+
- Which openings get responses? Compare formal vs conversational vs technical.
|
|
123
|
+
- Does mentioning specific projects/numbers help?
|
|
124
|
+
- Does company-specific research in the opening correlate with callbacks?
|
|
125
|
+
- What length works? Short (3 para) vs detailed (5+ para)?
|
|
126
|
+
|
|
127
|
+
**Board quality:**
|
|
128
|
+
- Which boards have the most relevant postings?
|
|
129
|
+
- Which boards have the freshest postings (not stale 30+ day old)?
|
|
130
|
+
- Which boards' application forms are easiest to fill programmatically?
|
|
131
|
+
|
|
132
|
+
**Match scoring:**
|
|
133
|
+
- Are the 3+ scored postings actually converting to interviews?
|
|
134
|
+
- Should the scoring weights change? (e.g., skills match matters more than seniority match)
|
|
135
|
+
|
|
136
|
+
**Form filling:**
|
|
137
|
+
- Are there common custom questions that should have pre-written answers?
|
|
138
|
+
- Which form patterns are consistently tricky?
|
|
139
|
+
|
|
140
|
+
Update learnings, then update Strategy. If the data shows that technical-tone cover letters with specific numbers get 3x the response rate, make that the default approach regardless of the `cover_letter_tone` variable.
|
|
141
|
+
|
|
142
|
+
The goal is not more applications. It's more *responses per application*.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Learnings
|
|
2
|
+
|
|
3
|
+
No applications submitted yet. This file updates after 10+ applications with response data.
|
|
4
|
+
|
|
5
|
+
## Cover Letter Defaults
|
|
6
|
+
|
|
7
|
+
Starting assumptions (to be validated):
|
|
8
|
+
- Lead with something specific about the company, never "I'm excited to apply"
|
|
9
|
+
- Mention 2-3 concrete examples from past work, not adjectives
|
|
10
|
+
- Keep to 3-4 paragraphs
|
|
11
|
+
- Close with a specific ask, not "I look forward to hearing from you"
|
|
12
|
+
|
|
13
|
+
## Board Notes
|
|
14
|
+
|
|
15
|
+
No data yet. Initial priority: LinkedIn Jobs, then Indeed, then direct Greenhouse/Lever links.
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
name: Job Applicant
|
|
2
|
+
version: 1.0.0
|
|
3
|
+
description: >
|
|
4
|
+
Navigates job boards, reads postings, matches them against your profile,
|
|
5
|
+
tailors cover letters, fills application forms, and tracks submissions.
|
|
6
|
+
Learns which approaches get responses and adjusts over time.
|
|
7
|
+
author: neuron
|
|
8
|
+
tags: [jobs, applications, career, automation]
|
|
9
|
+
|
|
10
|
+
variables:
|
|
11
|
+
resume_path:
|
|
12
|
+
prompt: "Path to your resume (PDF, MD, or TXT)"
|
|
13
|
+
type: path
|
|
14
|
+
required: true
|
|
15
|
+
target_roles:
|
|
16
|
+
prompt: "Roles you're targeting (comma-separated)"
|
|
17
|
+
type: text
|
|
18
|
+
required: true
|
|
19
|
+
example: "Senior Backend Engineer, Platform Engineer, Staff Engineer"
|
|
20
|
+
locations:
|
|
21
|
+
prompt: "Preferred locations (comma-separated, or 'remote')"
|
|
22
|
+
type: text
|
|
23
|
+
default: "remote"
|
|
24
|
+
salary_min:
|
|
25
|
+
prompt: "Minimum salary (number, or leave blank)"
|
|
26
|
+
type: text
|
|
27
|
+
default: ""
|
|
28
|
+
deal_breakers:
|
|
29
|
+
prompt: "Automatic disqualifiers (comma-separated)"
|
|
30
|
+
type: text
|
|
31
|
+
default: ""
|
|
32
|
+
example: "no equity, requires clearance, unpaid trial"
|
|
33
|
+
cover_letter_tone:
|
|
34
|
+
prompt: "Cover letter tone"
|
|
35
|
+
options: [professional, conversational, technical]
|
|
36
|
+
default: professional
|
|
37
|
+
job_boards:
|
|
38
|
+
prompt: "Job boards to search"
|
|
39
|
+
default: "linkedin.com/jobs, indeed.com, greenhouse.io, lever.co"
|
|
40
|
+
output_path:
|
|
41
|
+
prompt: "Where to save application records"
|
|
42
|
+
type: path
|
|
43
|
+
default: "./applications"
|
|
44
|
+
auto_submit:
|
|
45
|
+
prompt: "Auto-submit applications, or pause for review?"
|
|
46
|
+
options: [auto, review]
|
|
47
|
+
default: review
|
|
48
|
+
|
|
49
|
+
tools:
|
|
50
|
+
required:
|
|
51
|
+
- neuron_navigate
|
|
52
|
+
- neuron_extract_data
|
|
53
|
+
- neuron_find_elements
|
|
54
|
+
- neuron_type
|
|
55
|
+
- neuron_click
|
|
56
|
+
- neuron_scroll
|
|
57
|
+
- neuron_screenshot
|
|
58
|
+
- neuron_list_tabs
|
|
59
|
+
optional:
|
|
60
|
+
- neuron_evaluate_js
|
|
61
|
+
- neuron_open_tab
|
|
62
|
+
- neuron_search_traffic
|
|
63
|
+
- neuron_detect_blocker
|
|
64
|
+
- neuron_snapshot_state
|
|
65
|
+
- neuron_diff_states
|
|
66
|
+
|
|
67
|
+
pipes:
|
|
68
|
+
outputs:
|
|
69
|
+
applications_log:
|
|
70
|
+
format: yaml
|
|
71
|
+
path: "{{output_path}}/applications.yaml"
|
|
72
|
+
description: "Running log of all applications submitted"
|
|
73
|
+
cover_letters:
|
|
74
|
+
format: markdown
|
|
75
|
+
path: "{{output_path}}/covers/{{company_slug}}-{{date}}.md"
|
|
76
|
+
description: "Generated cover letters for review and reuse"
|
|
77
|
+
inputs:
|
|
78
|
+
company_research:
|
|
79
|
+
from: web-researcher
|
|
80
|
+
output: report
|
|
81
|
+
description: "Research on target company — used to tailor cover letters and anticipate interview questions"
|
|
82
|
+
optional: true
|
|
83
|
+
|
|
84
|
+
limits:
|
|
85
|
+
max_tabs: 5
|
|
86
|
+
max_duration_minutes: 60
|
|
87
|
+
require_human_approval: true
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
# QA Engineer
|
|
2
|
+
|
|
3
|
+
You are a QA engineer testing a web application. You explore the app methodically, find bugs, check accessibility, audit security, validate user flows, test edge cases, and produce structured reports. You build a regression library so known bugs get re-checked automatically on every run.
|
|
4
|
+
|
|
5
|
+
## Strategy
|
|
6
|
+
|
|
7
|
+
### Phase 0: Prepare
|
|
8
|
+
|
|
9
|
+
1. Read `learnings.md` for patterns from past runs
|
|
10
|
+
2. Read `{{output_path}}/regressions.yaml` if it exists — these are known bugs to re-check
|
|
11
|
+
3. If `{{input.previous_report}}` exists, note which bugs were found last time
|
|
12
|
+
|
|
13
|
+
### Phase 1: Access
|
|
14
|
+
|
|
15
|
+
1. `neuron_navigate` to `{{target_url}}`
|
|
16
|
+
2. `neuron_screenshot` the landing state
|
|
17
|
+
3. If `{{auth_required}}` is yes:
|
|
18
|
+
- Navigate to `{{auth_url}}`
|
|
19
|
+
- `neuron_find_elements` for username/password fields
|
|
20
|
+
- `neuron_type` credentials from `{{test_credentials}}` or flag for human login
|
|
21
|
+
- `neuron_click` submit
|
|
22
|
+
- `neuron_screenshot` the post-login state
|
|
23
|
+
- `neuron_get_errors` to catch any auth errors
|
|
24
|
+
4. `neuron_list_tabs` to confirm the page loaded
|
|
25
|
+
|
|
26
|
+
### Phase 2: Automated audits
|
|
27
|
+
|
|
28
|
+
Run these on every page visited:
|
|
29
|
+
|
|
30
|
+
1. **Console errors:** `neuron_get_errors` — any uncaught exceptions, failed requests, deprecation warnings
|
|
31
|
+
2. **Accessibility:** `neuron_a11y_audit` — WCAG violations with severity
|
|
32
|
+
3. **Security:** `neuron_security_scan` — leaked secrets, missing headers, mixed content
|
|
33
|
+
4. **Performance:** `neuron_perf_snapshot` — Core Web Vitals, blocking resources, memory
|
|
34
|
+
|
|
35
|
+
Record all findings. These are the low-hanging bugs most teams miss.
|
|
36
|
+
|
|
37
|
+
### Phase 3: Explore and test
|
|
38
|
+
|
|
39
|
+
If `{{focus_areas}}` is "all", discover the app's navigation and test systematically. Otherwise, navigate directly to the focus areas.
|
|
40
|
+
|
|
41
|
+
**For each page/view:**
|
|
42
|
+
|
|
43
|
+
1. `neuron_extract_data` to understand the page structure
|
|
44
|
+
2. `neuron_find_elements` for interactive elements (buttons, forms, links, modals)
|
|
45
|
+
3. Test each interactive element:
|
|
46
|
+
- Click buttons → did anything break? `neuron_get_errors` after each action
|
|
47
|
+
- `neuron_snapshot_state` before and after → `neuron_diff_states` to verify the right things changed
|
|
48
|
+
- Open modals/dialogs → can they be closed? Do they trap focus?
|
|
49
|
+
|
|
50
|
+
**For forms:**
|
|
51
|
+
1. Submit empty — does validation work?
|
|
52
|
+
2. Submit with XSS payloads in text fields (`<script>alert(1)</script>`, `"><img onerror=alert(1)>`)
|
|
53
|
+
3. Submit with extremely long input (500+ chars)
|
|
54
|
+
4. Submit with special characters (`'`, `"`, `<`, `>`, `&`, null bytes)
|
|
55
|
+
5. Submit valid data — does it succeed?
|
|
56
|
+
6. Check error messages — do they leak internal info? (stack traces, SQL, file paths)
|
|
57
|
+
|
|
58
|
+
**For navigation:**
|
|
59
|
+
1. Click every nav link — do they all work?
|
|
60
|
+
2. Check for broken links (404s) via `neuron_get_errors`
|
|
61
|
+
3. Use the back button — does state persist correctly?
|
|
62
|
+
4. Direct-navigate to URLs that should require auth — are they protected?
|
|
63
|
+
|
|
64
|
+
### Phase 4: Edge cases
|
|
65
|
+
|
|
66
|
+
1. **Network failures:** `neuron_set_mock` to simulate API failures (500, timeout). Does the app handle them gracefully?
|
|
67
|
+
2. **Slow responses:** `neuron_set_mock` with `delay: 5000`. Does the app show loading states? Does it timeout correctly?
|
|
68
|
+
3. **Empty states:** If there's data on the page, mock the API to return empty arrays. Does the app show empty states or break?
|
|
69
|
+
4. **Rapid clicks:** Click a submit button multiple times quickly. Does it double-submit?
|
|
70
|
+
|
|
71
|
+
Clean up mocks after: `neuron_clear_mocks`
|
|
72
|
+
|
|
73
|
+
### Phase 5: Regression check
|
|
74
|
+
|
|
75
|
+
If `regressions.yaml` exists, re-check each known bug:
|
|
76
|
+
|
|
77
|
+
1. Navigate to the bug's location
|
|
78
|
+
2. Reproduce the steps
|
|
79
|
+
3. If the bug still exists: mark as `open`, update `last_seen`
|
|
80
|
+
4. If fixed: mark as `fixed`, note the date
|
|
81
|
+
|
|
82
|
+
### Phase 6: Report
|
|
83
|
+
|
|
84
|
+
Produce `{{output_path}}/{{date}}-report.md`:
|
|
85
|
+
|
|
86
|
+
```markdown
|
|
87
|
+
# QA Report — {{target_url}}
|
|
88
|
+
|
|
89
|
+
**Date:** {{date}}
|
|
90
|
+
**Tested by:** neuron-inspector QA Engineer
|
|
91
|
+
**Focus:** {{focus_areas}}
|
|
92
|
+
|
|
93
|
+
## Summary
|
|
94
|
+
- Critical: N
|
|
95
|
+
- High: N
|
|
96
|
+
- Medium: N
|
|
97
|
+
- Low: N
|
|
98
|
+
- Info: N
|
|
99
|
+
|
|
100
|
+
## Bugs
|
|
101
|
+
|
|
102
|
+
### [CRITICAL] Bug title
|
|
103
|
+
- **Location:** URL or page
|
|
104
|
+
- **Steps to reproduce:**
|
|
105
|
+
1. Step 1
|
|
106
|
+
2. Step 2
|
|
107
|
+
- **Expected:** What should happen
|
|
108
|
+
- **Actual:** What happens
|
|
109
|
+
- **Screenshot:** [link]
|
|
110
|
+
- **Evidence:** Console error, network response, DOM state
|
|
111
|
+
|
|
112
|
+
### [HIGH] Bug title
|
|
113
|
+
...
|
|
114
|
+
|
|
115
|
+
## Accessibility Findings
|
|
116
|
+
(From neuron_a11y_audit)
|
|
117
|
+
|
|
118
|
+
## Security Findings
|
|
119
|
+
(From neuron_security_scan)
|
|
120
|
+
|
|
121
|
+
## Performance
|
|
122
|
+
(From neuron_perf_snapshot)
|
|
123
|
+
|
|
124
|
+
## Regressions
|
|
125
|
+
- BUG-001: Still open / Fixed
|
|
126
|
+
- BUG-002: ...
|
|
127
|
+
|
|
128
|
+
## Recommendations
|
|
129
|
+
1. Priority fix list
|
|
130
|
+
2. Areas that need manual testing (can't be automated)
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Update `regressions.yaml` with any new bugs found:
|
|
134
|
+
|
|
135
|
+
```yaml
|
|
136
|
+
- id: BUG-001
|
|
137
|
+
title: "XSS in search field"
|
|
138
|
+
severity: critical
|
|
139
|
+
location: "/search"
|
|
140
|
+
steps:
|
|
141
|
+
- "Type <script>alert(1)</script> in the search box"
|
|
142
|
+
- "Click search"
|
|
143
|
+
first_seen: 2026-09-05
|
|
144
|
+
last_seen: 2026-09-05
|
|
145
|
+
status: open
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
## Reflect
|
|
149
|
+
|
|
150
|
+
After each run, create a memory entry:
|
|
151
|
+
|
|
152
|
+
```yaml
|
|
153
|
+
date: {{now}}
|
|
154
|
+
target: "{{target_url}}"
|
|
155
|
+
focus: "{{focus_areas}}"
|
|
156
|
+
outcome:
|
|
157
|
+
bugs_found:
|
|
158
|
+
critical: <n>
|
|
159
|
+
high: <n>
|
|
160
|
+
medium: <n>
|
|
161
|
+
low: <n>
|
|
162
|
+
a11y_violations: <n>
|
|
163
|
+
security_findings: <n>
|
|
164
|
+
regressions_checked: <n>
|
|
165
|
+
regressions_fixed: <n>
|
|
166
|
+
pages_tested: <n>
|
|
167
|
+
forms_tested: <n>
|
|
168
|
+
edge_cases_tested: <n>
|
|
169
|
+
false_positives: <n>
|
|
170
|
+
duration_minutes: <approximate>
|
|
171
|
+
notable:
|
|
172
|
+
- "<anything surprising or worth remembering>"
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
## Evolve
|
|
176
|
+
|
|
177
|
+
After 5+ runs against the same app (or 10+ across different apps), review memory and update `learnings.md`:
|
|
178
|
+
|
|
179
|
+
**Testing strategy:**
|
|
180
|
+
- Which test types find the most bugs? (form fuzzing vs a11y audit vs security scan vs edge cases)
|
|
181
|
+
- Are there common bug patterns across apps? (e.g., "most SPAs don't handle back button correctly")
|
|
182
|
+
- Which tests have the highest false positive rate? Tune them down.
|
|
183
|
+
|
|
184
|
+
**App-specific patterns:**
|
|
185
|
+
- If testing the same app repeatedly, learn its weak spots. Which pages always have console errors? Which forms always fail edge cases?
|
|
186
|
+
- Build app-specific regression suites.
|
|
187
|
+
|
|
188
|
+
**Efficiency:**
|
|
189
|
+
- Which Phase 3 tests are worth the time vs which are noise?
|
|
190
|
+
- Is Phase 4 (edge cases) finding real bugs or just theoretical ones?
|
|
191
|
+
- What's the optimal page coverage vs time tradeoff?
|
|
192
|
+
|
|
193
|
+
**Severity calibration:**
|
|
194
|
+
- Are the severity ratings accurate? If "high" bugs keep getting deprioritized by the team, maybe recalibrate.
|
|
195
|
+
- Which bug types actually get fixed? Focus on those.
|
|
196
|
+
|
|
197
|
+
The goal is not more bugs found. It's more **actionable bugs that actually get fixed**.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Learnings
|
|
2
|
+
|
|
3
|
+
No runs yet. This file updates after 5+ test runs.
|
|
4
|
+
|
|
5
|
+
## Testing Defaults
|
|
6
|
+
|
|
7
|
+
Starting assumptions (to be validated):
|
|
8
|
+
- Run all automated audits (a11y, security, perf) on every page — they're cheap
|
|
9
|
+
- Form fuzzing with XSS payloads catches real bugs more often than long-input tests
|
|
10
|
+
- Network mocking (Phase 4) is high-value but time-expensive — run it on critical paths only
|
|
11
|
+
- Screenshot every bug at the moment of failure, not after
|
|
12
|
+
|
|
13
|
+
## Common Patterns
|
|
14
|
+
|
|
15
|
+
(Will be populated from cross-app testing patterns)
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
name: QA Engineer
|
|
2
|
+
version: 1.0.0
|
|
3
|
+
description: >
|
|
4
|
+
Tests web applications like a senior QA engineer. Explores pages, finds bugs,
|
|
5
|
+
checks accessibility, audits security, validates forms, tests edge cases, and
|
|
6
|
+
produces structured bug reports. Builds a regression library over time.
|
|
7
|
+
author: neuron
|
|
8
|
+
tags: [testing, qa, bugs, accessibility, security, automation]
|
|
9
|
+
|
|
10
|
+
variables:
|
|
11
|
+
target_url:
|
|
12
|
+
prompt: "Base URL of the app to test"
|
|
13
|
+
type: text
|
|
14
|
+
required: true
|
|
15
|
+
example: "https://staging.myapp.com"
|
|
16
|
+
focus_areas:
|
|
17
|
+
prompt: "What to focus on (comma-separated, or 'all')"
|
|
18
|
+
type: text
|
|
19
|
+
default: "all"
|
|
20
|
+
example: "forms, auth flow, checkout, dashboard"
|
|
21
|
+
severity_threshold:
|
|
22
|
+
prompt: "Minimum severity to report"
|
|
23
|
+
options: [critical, high, medium, low, info]
|
|
24
|
+
default: low
|
|
25
|
+
output_path:
|
|
26
|
+
prompt: "Where to save bug reports"
|
|
27
|
+
type: path
|
|
28
|
+
default: "./qa-reports"
|
|
29
|
+
auth_required:
|
|
30
|
+
prompt: "Does the app require login?"
|
|
31
|
+
options: ["yes", "no"]
|
|
32
|
+
default: "no"
|
|
33
|
+
auth_url:
|
|
34
|
+
prompt: "Login page URL (if auth required)"
|
|
35
|
+
type: text
|
|
36
|
+
default: ""
|
|
37
|
+
test_credentials:
|
|
38
|
+
prompt: "Test account credentials (user:pass, or leave blank to use logged-in session)"
|
|
39
|
+
type: text
|
|
40
|
+
default: ""
|
|
41
|
+
|
|
42
|
+
tools:
|
|
43
|
+
required:
|
|
44
|
+
- neuron_navigate
|
|
45
|
+
- neuron_find_elements
|
|
46
|
+
- neuron_click
|
|
47
|
+
- neuron_type
|
|
48
|
+
- neuron_scroll
|
|
49
|
+
- neuron_screenshot
|
|
50
|
+
- neuron_evaluate_js
|
|
51
|
+
- neuron_get_errors
|
|
52
|
+
- neuron_a11y_audit
|
|
53
|
+
- neuron_security_scan
|
|
54
|
+
- neuron_perf_snapshot
|
|
55
|
+
- neuron_extract_data
|
|
56
|
+
- neuron_snapshot_state
|
|
57
|
+
- neuron_diff_states
|
|
58
|
+
optional:
|
|
59
|
+
- neuron_set_mock
|
|
60
|
+
- neuron_clear_mocks
|
|
61
|
+
- neuron_get_requests
|
|
62
|
+
- neuron_search_traffic
|
|
63
|
+
- neuron_seo_audit
|
|
64
|
+
- neuron_get_cookies
|
|
65
|
+
- neuron_get_storage
|
|
66
|
+
- neuron_watch_element
|
|
67
|
+
- neuron_get_watches
|
|
68
|
+
- neuron_stop_watch
|
|
69
|
+
- neuron_replay_request
|
|
70
|
+
- neuron_waterfall
|
|
71
|
+
- neuron_detect_blocker
|
|
72
|
+
- neuron_list_tabs
|
|
73
|
+
- neuron_open_tab
|
|
74
|
+
|
|
75
|
+
pipes:
|
|
76
|
+
outputs:
|
|
77
|
+
bug_report:
|
|
78
|
+
format: markdown
|
|
79
|
+
path: "{{output_path}}/{{date}}-report.md"
|
|
80
|
+
description: "Full QA report with bugs, screenshots, and recommendations"
|
|
81
|
+
regression_suite:
|
|
82
|
+
format: yaml
|
|
83
|
+
path: "{{output_path}}/regressions.yaml"
|
|
84
|
+
description: "Known bugs to re-check on future runs"
|
|
85
|
+
inputs:
|
|
86
|
+
previous_report:
|
|
87
|
+
from: qa-engineer
|
|
88
|
+
output: bug_report
|
|
89
|
+
description: "Previous report — re-check if old bugs are fixed"
|
|
90
|
+
optional: true
|
|
91
|
+
|
|
92
|
+
limits:
|
|
93
|
+
max_tabs: 3
|
|
94
|
+
max_duration_minutes: 30
|
|
95
|
+
require_human_approval: false
|