playwright-intelligence-engine 2.0.1 → 2.0.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/README.md +229 -229
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/core/version.d.ts +3 -3
- package/dist/index.js +81 -24
- package/package.json +76 -76
- package/src/authoring/author.ts +81 -81
- package/src/authoring/generation-contract.ts +283 -283
- package/src/authoring/hybrid-author.ts +115 -115
- package/src/authoring/index.ts +7 -7
- package/src/authoring/llm-author.ts +282 -282
- package/src/authoring/naming/name-plan.ts +28 -28
- package/src/authoring/naming/name-planner.ts +339 -339
- package/src/authoring/naming/naming-linter.ts +292 -292
- package/src/cli/index.ts +1238 -1172
- package/src/collectors/git-diff-collector.ts +190 -190
- package/src/core/version.ts +25 -25
- package/src/diagnostics/diagnostic-report.ts +204 -204
- package/src/diagnostics/failure-classifier.ts +701 -701
- package/src/evaluation/repository-runner.ts +197 -197
- package/src/gate/quality.ts +101 -101
- package/src/generator/architecture-generator.ts +582 -582
- package/src/generator/assertion-quality-gate.ts +88 -88
- package/src/generator/candidate-writer.ts +288 -288
- package/src/generator/test-generator.ts +52 -52
- package/src/index.ts +107 -107
- package/src/intelligence/evidence-bundle.ts +300 -300
- package/src/intelligence/generation-agent.ts +561 -561
- package/src/intelligence/generation-verifier.ts +1115 -1115
- package/src/intelligence/locator-disambiguation-engine.ts +331 -331
- package/src/intelligence/project-intelligence.ts +140 -140
- package/src/intelligence/repository-profile.ts +796 -796
- package/src/intelligence/trace-proposal-workflow.ts +318 -318
- package/src/intelligence/workflow-planner.ts +966 -966
- package/src/mcp/server.ts +970 -970
- package/src/perception/app-model.ts +32 -32
- package/src/perception/crawler.ts +263 -263
- package/src/perception/index.ts +3 -3
- package/src/repair/assertion-hasher.ts +386 -386
- package/src/repair/diff-allowlist.ts +612 -612
- package/src/repair/intent-validator.ts +761 -761
- package/src/repair/repair-planner.ts +467 -467
- package/src/repair/statement-patcher.ts +544 -544
- package/src/reproduce/interactive-workflow-runner.ts +828 -828
- package/src/sandbox/execution-runner.ts +408 -408
- package/src/selector/abstention-policy.ts +175 -175
- package/src/selector/candidate-extractor.ts +343 -343
- package/src/selector/repair-candidate-ranker.ts +92 -92
- package/src/selector/selector-scorer.ts +344 -344
package/README.md
CHANGED
|
@@ -1,229 +1,229 @@
|
|
|
1
|
-
# Playwright Intelligence Engine (`pw-intel`)
|
|
2
|
-
|
|
3
|
-
> Fast, verification-first failure diagnosis, autonomous self-healing, and test generation for Microsoft Playwright suites.
|
|
4
|
-
|
|
5
|
-
[](https://www.npmjs.com/package/playwright-intelligence-engine)
|
|
6
|
-
[](LICENSE)
|
|
7
|
-
[](https://nodejs.org/)
|
|
8
|
-
[](https://playwright.dev/)
|
|
9
|
-
|
|
10
|
-
---
|
|
11
|
-
|
|
12
|
-
## 1. Installation
|
|
13
|
-
|
|
14
|
-
Run without installing via `npx`:
|
|
15
|
-
```bash
|
|
16
|
-
npx pw-intel --help
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
Or install in your project:
|
|
20
|
-
```bash
|
|
21
|
-
npm install --save-dev playwright-intelligence-engine
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
Or install globally:
|
|
25
|
-
```bash
|
|
26
|
-
npm install -g playwright-intelligence-engine
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
*(Both `pw-intel` and `playwright-intelligence-engine` commands are available).*
|
|
30
|
-
|
|
31
|
-
---
|
|
32
|
-
|
|
33
|
-
## 2. Project Setup & LLM Configuration
|
|
34
|
-
|
|
35
|
-
Initialize PIE in your Playwright repository:
|
|
36
|
-
|
|
37
|
-
```bash
|
|
38
|
-
npx pw-intel init
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
### Providing your LLM API Key (Optional)
|
|
42
|
-
|
|
43
|
-
> **Note:** Failure diagnosis, trace analysis, and AST test repairs run **100% offline and locally** without an LLM key.
|
|
44
|
-
> An API key is only needed if you want AI-assisted test generation (`pw-intel generate-agent`).
|
|
45
|
-
|
|
46
|
-
You can configure an LLM key in any of three ways:
|
|
47
|
-
|
|
48
|
-
#### Option A: During `init`
|
|
49
|
-
```bash
|
|
50
|
-
npx pw-intel init --api-key sk-your-openai-or-deepseek-key --model gpt-4o
|
|
51
|
-
```
|
|
52
|
-
*This automatically creates `.env` and adds it to your `.gitignore`.*
|
|
53
|
-
|
|
54
|
-
#### Option B: Environment Variable
|
|
55
|
-
```bash
|
|
56
|
-
export OPENAI_API_KEY="sk-..."
|
|
57
|
-
# or
|
|
58
|
-
export PIE_LLM_API_KEY="sk-..."
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
#### Option C: In `.env`
|
|
62
|
-
Create `.env` in your project root:
|
|
63
|
-
```ini
|
|
64
|
-
PIE_LLM_API_KEY=sk-...
|
|
65
|
-
PIE_LLM_MODEL=gpt-4o
|
|
66
|
-
PIE_LLM_ENDPOINT=https://api.openai.com/v1/chat/completions
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
Verify your setup at any time:
|
|
70
|
-
```bash
|
|
71
|
-
npx pw-intel doctor
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
---
|
|
75
|
-
|
|
76
|
-
## 3. How to Use
|
|
77
|
-
|
|
78
|
-
### 🔍 A. Diagnose a Failing Test
|
|
79
|
-
Ingest a Playwright trace archive (`trace.zip`) to find the exact root cause:
|
|
80
|
-
|
|
81
|
-
```bash
|
|
82
|
-
npx pw-intel diagnose ./test-results/trace.zip
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
**Output example:**
|
|
86
|
-
```json
|
|
87
|
-
{
|
|
88
|
-
"category": "LOCATOR_DRIFT",
|
|
89
|
-
"confidence": 0.94,
|
|
90
|
-
"action": "click",
|
|
91
|
-
"failingSelector": "#checkout-btn-v1",
|
|
92
|
-
"suggestedSelector": "button:has-text(\"Proceed to Checkout\")",
|
|
93
|
-
"targetFile": "e2e/pages/CartPage.ts",
|
|
94
|
-
"evidence": "Element ID changed dynamically; stable accessible role match found."
|
|
95
|
-
}
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
If the failure was caused by a backend crash (HTTP 500) or expired authentication (HTTP 401), PIE flags it immediately and abstains from modifying locators.
|
|
99
|
-
|
|
100
|
-
---
|
|
101
|
-
|
|
102
|
-
### 🔧 B. Autonomous Test Repair (Safe Worktrees)
|
|
103
|
-
Repair a broken test or Page Object without risking your active Git branch:
|
|
104
|
-
|
|
105
|
-
```bash
|
|
106
|
-
# 1. Plan and test the repair in an isolated Git worktree:
|
|
107
|
-
npx pw-intel autonomous-repair ./test-results/trace.zip --execute
|
|
108
|
-
|
|
109
|
-
# 2. Check the cryptographic proposal:
|
|
110
|
-
npx pw-intel approve <proposalId>
|
|
111
|
-
|
|
112
|
-
# 3. Promote the verified fix atomically to your workspace:
|
|
113
|
-
npx pw-intel promote --token <approvalToken>
|
|
114
|
-
```
|
|
115
|
-
|
|
116
|
-
**The Safety Guarantee:**
|
|
117
|
-
- PIE **never** deletes or weakens your assertions (`expect(...)`).
|
|
118
|
-
- PIE **never** alters test inputs or reorders user actions.
|
|
119
|
-
- All repairs are executed and proven passing in a background worktree before promotion.
|
|
120
|
-
|
|
121
|
-
---
|
|
122
|
-
|
|
123
|
-
### 🚀 C. Generate Tests from Requirements
|
|
124
|
-
Generate complete Playwright test suites and Page Objects that conform to your repository's conventions:
|
|
125
|
-
|
|
126
|
-
```bash
|
|
127
|
-
npx pw-intel generate-agent ./requirements.json --mode brownfield --write --verify
|
|
128
|
-
```
|
|
129
|
-
|
|
130
|
-
**Arguments:**
|
|
131
|
-
- `--mode brownfield`: Reuses existing fixtures, auth states, and Page Objects without generating duplicate login steps.
|
|
132
|
-
- `--mode greenfield`: Scaffolds a new end-to-end testing architecture from scratch.
|
|
133
|
-
- `--write`: Saves the generated files to disk.
|
|
134
|
-
- `--verify`: Runs TypeScript typecheck and Playwright discovery to ensure generated code compiles.
|
|
135
|
-
|
|
136
|
-
---
|
|
137
|
-
|
|
138
|
-
### 🧪 D. Reproduce a Spec with Live Instrumentation
|
|
139
|
-
Rerun a flaky test with live DOM snapshots, network capture, and console logs:
|
|
140
|
-
|
|
141
|
-
```bash
|
|
142
|
-
npx pw-intel reproduce tests/checkout.spec.ts
|
|
143
|
-
```
|
|
144
|
-
|
|
145
|
-
---
|
|
146
|
-
|
|
147
|
-
### 📊 E. CI/CD Quality Gate & SARIF Reporting
|
|
148
|
-
Convert Playwright test results into GitHub Actions annotations and SARIF security/flakiness reports:
|
|
149
|
-
|
|
150
|
-
```bash
|
|
151
|
-
npx pw-intel ci-report ./test-results/results.json --sarif-out ./pie-results.sarif
|
|
152
|
-
```
|
|
153
|
-
|
|
154
|
-
---
|
|
155
|
-
|
|
156
|
-
## 4. Cursor / Claude Code IDE Integration (MCP Server)
|
|
157
|
-
|
|
158
|
-
PIE includes a built-in Model Context Protocol (MCP) server so AI coding assistants can diagnose traces and fix tests directly inside your IDE.
|
|
159
|
-
|
|
160
|
-
### For Cursor / Windsurf
|
|
161
|
-
Add to `.cursor/mcp.json`:
|
|
162
|
-
```json
|
|
163
|
-
{
|
|
164
|
-
"mcpServers": {
|
|
165
|
-
"playwright-intelligence": {
|
|
166
|
-
"command": "npx",
|
|
167
|
-
"args": ["-y", "playwright-intelligence-engine", "mcp"]
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
```
|
|
172
|
-
|
|
173
|
-
### For Claude Desktop / Claude Code
|
|
174
|
-
Add to `claude_desktop_config.json`:
|
|
175
|
-
```json
|
|
176
|
-
{
|
|
177
|
-
"mcpServers": {
|
|
178
|
-
"pw-intel": {
|
|
179
|
-
"command": "npx",
|
|
180
|
-
"args": ["-y", "playwright-intelligence-engine", "mcp"]
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
```
|
|
185
|
-
|
|
186
|
-
**Available MCP Tools:**
|
|
187
|
-
- `diagnose_trace`: Diagnoses Playwright traces and provides root causes.
|
|
188
|
-
- `repair_page_object`: Stages isolated repairs with cryptographic approval tokens.
|
|
189
|
-
- `generate_playwright_test`: Generates tests matching your repository's conventions.
|
|
190
|
-
- `ingest_playwright_report`: Analyzes test run failures and flakiness.
|
|
191
|
-
|
|
192
|
-
---
|
|
193
|
-
|
|
194
|
-
## 5. CLI Command Cheat Sheet
|
|
195
|
-
|
|
196
|
-
| Command | Usage | Description |
|
|
197
|
-
| :--- | :--- | :--- |
|
|
198
|
-
| `init` | `pw-intel init [--api-key <k>]` | Initializes `.pie/config.json` & optional LLM credentials |
|
|
199
|
-
| `doctor` | `pw-intel doctor` | Verifies Node, Git, Playwright & LLM readiness |
|
|
200
|
-
| `diagnose` | `pw-intel diagnose <trace.zip>` | Ingests trace and outputs causal root cause |
|
|
201
|
-
| `autonomous-repair` | `pw-intel autonomous-repair <trace.zip> --execute` | Verifies repair in an isolated Git worktree |
|
|
202
|
-
| `approve` | `pw-intel approve <proposalId>` | Authorizes a verified repair proposal |
|
|
203
|
-
| `promote` | `pw-intel promote --token <token>` | Applies authorized fix atomically to active code |
|
|
204
|
-
| `generate-agent` | `pw-intel generate-agent <reqs.json> --write` | Generates tests matching project conventions |
|
|
205
|
-
| `reproduce` | `pw-intel reproduce <spec.ts>` | Reruns spec with live DOM and network capture |
|
|
206
|
-
| `ci-report` | `pw-intel ci-report <results.json>` | Generates CI annotations and SARIF report |
|
|
207
|
-
| `mcp` | `pw-intel mcp` | Starts the Model Context Protocol stdio server |
|
|
208
|
-
|
|
209
|
-
---
|
|
210
|
-
|
|
211
|
-
## 6. Detailed Documentation
|
|
212
|
-
|
|
213
|
-
- [CLI Reference Guide](docs/CLI_REFERENCE.md)
|
|
214
|
-
- [System Architecture](docs/ARCHITECTURE.md)
|
|
215
|
-
- [Benchmark Methodology & Results](docs/BENCHMARK.md)
|
|
216
|
-
- [Intent Invariants & Verification Guarantees](docs/INTENT_INVARIANTS.md)
|
|
217
|
-
- [MCP Server Setup](docs/MCP_INTEGRATION.md)
|
|
218
|
-
|
|
219
|
-
---
|
|
220
|
-
|
|
221
|
-
## Community & Contributing
|
|
222
|
-
|
|
223
|
-
Contributions, feedback, and bug reports are warmly welcome! If Playwright Intelligence Engine saves you debugging time or helps stabilize your test suite, please consider giving it a ⭐ on [GitHub](https://github.com/lst2121/playwright-intelligence-engine).
|
|
224
|
-
|
|
225
|
-
---
|
|
226
|
-
|
|
227
|
-
## License
|
|
228
|
-
|
|
229
|
-
Apache-2.0. See [LICENSE](LICENSE) for details.
|
|
1
|
+
# Playwright Intelligence Engine (`pw-intel`)
|
|
2
|
+
|
|
3
|
+
> Fast, verification-first failure diagnosis, autonomous self-healing, and test generation for Microsoft Playwright suites.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/playwright-intelligence-engine)
|
|
6
|
+
[](LICENSE)
|
|
7
|
+
[](https://nodejs.org/)
|
|
8
|
+
[](https://playwright.dev/)
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## 1. Installation
|
|
13
|
+
|
|
14
|
+
Run without installing via `npx`:
|
|
15
|
+
```bash
|
|
16
|
+
npx pw-intel --help
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Or install in your project:
|
|
20
|
+
```bash
|
|
21
|
+
npm install --save-dev playwright-intelligence-engine
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Or install globally:
|
|
25
|
+
```bash
|
|
26
|
+
npm install -g playwright-intelligence-engine
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
*(Both `pw-intel` and `playwright-intelligence-engine` commands are available).*
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## 2. Project Setup & LLM Configuration
|
|
34
|
+
|
|
35
|
+
Initialize PIE in your Playwright repository:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
npx pw-intel init
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Providing your LLM API Key (Optional)
|
|
42
|
+
|
|
43
|
+
> **Note:** Failure diagnosis, trace analysis, and AST test repairs run **100% offline and locally** without an LLM key.
|
|
44
|
+
> An API key is only needed if you want AI-assisted test generation (`pw-intel generate-agent`).
|
|
45
|
+
|
|
46
|
+
You can configure an LLM key in any of three ways:
|
|
47
|
+
|
|
48
|
+
#### Option A: During `init`
|
|
49
|
+
```bash
|
|
50
|
+
npx pw-intel init --api-key sk-your-openai-or-deepseek-key --model gpt-4o
|
|
51
|
+
```
|
|
52
|
+
*This automatically creates `.env` and adds it to your `.gitignore`.*
|
|
53
|
+
|
|
54
|
+
#### Option B: Environment Variable
|
|
55
|
+
```bash
|
|
56
|
+
export OPENAI_API_KEY="sk-..."
|
|
57
|
+
# or
|
|
58
|
+
export PIE_LLM_API_KEY="sk-..."
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
#### Option C: In `.env`
|
|
62
|
+
Create `.env` in your project root:
|
|
63
|
+
```ini
|
|
64
|
+
PIE_LLM_API_KEY=sk-...
|
|
65
|
+
PIE_LLM_MODEL=gpt-4o
|
|
66
|
+
PIE_LLM_ENDPOINT=https://api.openai.com/v1/chat/completions
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Verify your setup at any time:
|
|
70
|
+
```bash
|
|
71
|
+
npx pw-intel doctor
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## 3. How to Use
|
|
77
|
+
|
|
78
|
+
### 🔍 A. Diagnose a Failing Test
|
|
79
|
+
Ingest a Playwright trace archive (`trace.zip`) to find the exact root cause:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
npx pw-intel diagnose ./test-results/trace.zip
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
**Output example:**
|
|
86
|
+
```json
|
|
87
|
+
{
|
|
88
|
+
"category": "LOCATOR_DRIFT",
|
|
89
|
+
"confidence": 0.94,
|
|
90
|
+
"action": "click",
|
|
91
|
+
"failingSelector": "#checkout-btn-v1",
|
|
92
|
+
"suggestedSelector": "button:has-text(\"Proceed to Checkout\")",
|
|
93
|
+
"targetFile": "e2e/pages/CartPage.ts",
|
|
94
|
+
"evidence": "Element ID changed dynamically; stable accessible role match found."
|
|
95
|
+
}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
If the failure was caused by a backend crash (HTTP 500) or expired authentication (HTTP 401), PIE flags it immediately and abstains from modifying locators.
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
### 🔧 B. Autonomous Test Repair (Safe Worktrees)
|
|
103
|
+
Repair a broken test or Page Object without risking your active Git branch:
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
# 1. Plan and test the repair in an isolated Git worktree:
|
|
107
|
+
npx pw-intel autonomous-repair ./test-results/trace.zip --execute
|
|
108
|
+
|
|
109
|
+
# 2. Check the cryptographic proposal:
|
|
110
|
+
npx pw-intel approve <proposalId>
|
|
111
|
+
|
|
112
|
+
# 3. Promote the verified fix atomically to your workspace:
|
|
113
|
+
npx pw-intel promote --token <approvalToken>
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
**The Safety Guarantee:**
|
|
117
|
+
- PIE **never** deletes or weakens your assertions (`expect(...)`).
|
|
118
|
+
- PIE **never** alters test inputs or reorders user actions.
|
|
119
|
+
- All repairs are executed and proven passing in a background worktree before promotion.
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
### 🚀 C. Generate Tests from Requirements
|
|
124
|
+
Generate complete Playwright test suites and Page Objects that conform to your repository's conventions:
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
npx pw-intel generate-agent ./requirements.json --mode brownfield --write --verify
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
**Arguments:**
|
|
131
|
+
- `--mode brownfield`: Reuses existing fixtures, auth states, and Page Objects without generating duplicate login steps.
|
|
132
|
+
- `--mode greenfield`: Scaffolds a new end-to-end testing architecture from scratch.
|
|
133
|
+
- `--write`: Saves the generated files to disk.
|
|
134
|
+
- `--verify`: Runs TypeScript typecheck and Playwright discovery to ensure generated code compiles.
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
### 🧪 D. Reproduce a Spec with Live Instrumentation
|
|
139
|
+
Rerun a flaky test with live DOM snapshots, network capture, and console logs:
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
npx pw-intel reproduce tests/checkout.spec.ts
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
### 📊 E. CI/CD Quality Gate & SARIF Reporting
|
|
148
|
+
Convert Playwright test results into GitHub Actions annotations and SARIF security/flakiness reports:
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
npx pw-intel ci-report ./test-results/results.json --sarif-out ./pie-results.sarif
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## 4. Cursor / Claude Code IDE Integration (MCP Server)
|
|
157
|
+
|
|
158
|
+
PIE includes a built-in Model Context Protocol (MCP) server so AI coding assistants can diagnose traces and fix tests directly inside your IDE.
|
|
159
|
+
|
|
160
|
+
### For Cursor / Windsurf
|
|
161
|
+
Add to `.cursor/mcp.json`:
|
|
162
|
+
```json
|
|
163
|
+
{
|
|
164
|
+
"mcpServers": {
|
|
165
|
+
"playwright-intelligence": {
|
|
166
|
+
"command": "npx",
|
|
167
|
+
"args": ["-y", "playwright-intelligence-engine", "mcp"]
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### For Claude Desktop / Claude Code
|
|
174
|
+
Add to `claude_desktop_config.json`:
|
|
175
|
+
```json
|
|
176
|
+
{
|
|
177
|
+
"mcpServers": {
|
|
178
|
+
"pw-intel": {
|
|
179
|
+
"command": "npx",
|
|
180
|
+
"args": ["-y", "playwright-intelligence-engine", "mcp"]
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
**Available MCP Tools:**
|
|
187
|
+
- `diagnose_trace`: Diagnoses Playwright traces and provides root causes.
|
|
188
|
+
- `repair_page_object`: Stages isolated repairs with cryptographic approval tokens.
|
|
189
|
+
- `generate_playwright_test`: Generates tests matching your repository's conventions.
|
|
190
|
+
- `ingest_playwright_report`: Analyzes test run failures and flakiness.
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
## 5. CLI Command Cheat Sheet
|
|
195
|
+
|
|
196
|
+
| Command | Usage | Description |
|
|
197
|
+
| :--- | :--- | :--- |
|
|
198
|
+
| `init` | `pw-intel init [--api-key <k>]` | Initializes `.pie/config.json` & optional LLM credentials |
|
|
199
|
+
| `doctor` | `pw-intel doctor` | Verifies Node, Git, Playwright & LLM readiness |
|
|
200
|
+
| `diagnose` | `pw-intel diagnose <trace.zip>` | Ingests trace and outputs causal root cause |
|
|
201
|
+
| `autonomous-repair` | `pw-intel autonomous-repair <trace.zip> --execute` | Verifies repair in an isolated Git worktree |
|
|
202
|
+
| `approve` | `pw-intel approve <proposalId>` | Authorizes a verified repair proposal |
|
|
203
|
+
| `promote` | `pw-intel promote --token <token>` | Applies authorized fix atomically to active code |
|
|
204
|
+
| `generate-agent` | `pw-intel generate-agent <reqs.json> --write` | Generates tests matching project conventions |
|
|
205
|
+
| `reproduce` | `pw-intel reproduce <spec.ts>` | Reruns spec with live DOM and network capture |
|
|
206
|
+
| `ci-report` | `pw-intel ci-report <results.json>` | Generates CI annotations and SARIF report |
|
|
207
|
+
| `mcp` | `pw-intel mcp` | Starts the Model Context Protocol stdio server |
|
|
208
|
+
|
|
209
|
+
---
|
|
210
|
+
|
|
211
|
+
## 6. Detailed Documentation
|
|
212
|
+
|
|
213
|
+
- [CLI Reference Guide](docs/CLI_REFERENCE.md)
|
|
214
|
+
- [System Architecture](docs/ARCHITECTURE.md)
|
|
215
|
+
- [Benchmark Methodology & Results](docs/BENCHMARK.md)
|
|
216
|
+
- [Intent Invariants & Verification Guarantees](docs/INTENT_INVARIANTS.md)
|
|
217
|
+
- [MCP Server Setup](docs/MCP_INTEGRATION.md)
|
|
218
|
+
|
|
219
|
+
---
|
|
220
|
+
|
|
221
|
+
## Community & Contributing
|
|
222
|
+
|
|
223
|
+
Contributions, feedback, and bug reports are warmly welcome! If Playwright Intelligence Engine saves you debugging time or helps stabilize your test suite, please consider giving it a ⭐ on [GitHub](https://github.com/lst2121/playwright-intelligence-engine).
|
|
224
|
+
|
|
225
|
+
---
|
|
226
|
+
|
|
227
|
+
## License
|
|
228
|
+
|
|
229
|
+
Apache-2.0. See [LICENSE](LICENSE) for details.
|
package/dist/cli/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AAmFA,wBAAsB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAkgC1D"}
|
package/dist/core/version.d.ts
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
* Product identity is kept in one place so the CLI, MCP server, and execution
|
|
3
3
|
* proofs cannot silently advertise different versions.
|
|
4
4
|
*/
|
|
5
|
-
export declare const PACKAGE_VERSION = "2.0.
|
|
6
|
-
export declare const ENGINE_MILESTONE = "2.0.
|
|
7
|
-
export declare const PROOF_VERSION = "2.0.
|
|
5
|
+
export declare const PACKAGE_VERSION = "2.0.2";
|
|
6
|
+
export declare const ENGINE_MILESTONE = "2.0.2";
|
|
7
|
+
export declare const PROOF_VERSION = "2.0.2";
|
|
8
8
|
export interface RuntimeProvenance {
|
|
9
9
|
sourceRevision: string;
|
|
10
10
|
workspaceDirty: boolean;
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// src/core/version.ts
|
|
2
2
|
import { execFileSync } from "child_process";
|
|
3
|
-
var PACKAGE_VERSION = "2.0.
|
|
4
|
-
var ENGINE_MILESTONE = "2.0.
|
|
3
|
+
var PACKAGE_VERSION = "2.0.2";
|
|
4
|
+
var ENGINE_MILESTONE = "2.0.2";
|
|
5
5
|
var PROOF_VERSION = ENGINE_MILESTONE;
|
|
6
6
|
function getRuntimeProvenance(root = process.cwd()) {
|
|
7
7
|
try {
|
|
@@ -358,8 +358,8 @@ var ArchiveReader = class _ArchiveReader {
|
|
|
358
358
|
}
|
|
359
359
|
const normalizedEntry = entryName.replace(/\\/g, "/");
|
|
360
360
|
const targetFilePath = path.resolve(resolvedDest, normalizedEntry);
|
|
361
|
-
const
|
|
362
|
-
if (
|
|
361
|
+
const relative3 = path.relative(resolvedDest, targetFilePath);
|
|
362
|
+
if (relative3.startsWith("..") || path.isAbsolute(relative3) || path.win32.isAbsolute(relative3) || path.posix.isAbsolute(relative3)) {
|
|
363
363
|
throw new ZipSlipSecurityError(entry.entryName);
|
|
364
364
|
}
|
|
365
365
|
entryNames.push(entry.entryName);
|
|
@@ -2116,8 +2116,8 @@ async function inspectRepository(root) {
|
|
|
2116
2116
|
}
|
|
2117
2117
|
}
|
|
2118
2118
|
if (!packageJson || !packagePath) throw new Error("No readable package.json found");
|
|
2119
|
-
const
|
|
2120
|
-
const configs =
|
|
2119
|
+
const relative3 = files.map((file) => path2.relative(absoluteRoot, file));
|
|
2120
|
+
const configs = relative3.filter((file) => /(^|[\\/])playwright(?:\.[^.]*)?\.config\.(?:ts|js|mjs|cjs)$/i.test(file));
|
|
2121
2121
|
const allDependencies = { ...packageJson.dependencies, ...packageJson.devDependencies };
|
|
2122
2122
|
const hasPlaywright = Object.keys(allDependencies).some((name) => name === "@playwright/test" || name === "playwright");
|
|
2123
2123
|
const packageRoot = path2.dirname(packagePath);
|
|
@@ -2132,10 +2132,10 @@ async function inspectRepository(root) {
|
|
|
2132
2132
|
playwrightVersion: allDependencies["@playwright/test"] ?? allDependencies.playwright,
|
|
2133
2133
|
hasPlaywrightConfig: configs.length > 0,
|
|
2134
2134
|
playwrightConfigs: configs,
|
|
2135
|
-
testFiles:
|
|
2136
|
-
pageObjectFiles:
|
|
2137
|
-
fixtureFiles:
|
|
2138
|
-
hasDocker:
|
|
2135
|
+
testFiles: relative3.filter((file) => /(?:^|[\\/])(?:tests?|e2e)(?:[\\/]).*\.(?:spec|test)\.(?:ts|tsx|js|jsx|mjs|cjs)$/i.test(file)).length,
|
|
2136
|
+
pageObjectFiles: relative3.filter((file) => /(?:page|pages|pom|page-objects?)[\\/].*\.(?:ts|tsx|js|jsx)$/i.test(file)).length,
|
|
2137
|
+
fixtureFiles: relative3.filter((file) => /fixture/i.test(file) && /\.(?:ts|tsx|js|jsx)$/.test(file)).length,
|
|
2138
|
+
hasDocker: relative3.some((file) => /(?:^|[\\/])(?:docker-compose[^\\/]*|Dockerfile(?:\..*)?)$/i.test(file)),
|
|
2139
2139
|
hasLocalWebServerHint: Object.values(packageJson.scripts ?? {}).some((script) => /(?:next|vite|dev|start|serve)/i.test(script)),
|
|
2140
2140
|
scripts: packageJson.scripts ?? {},
|
|
2141
2141
|
status: hasPlaywright || configs.length > 0 ? "DISCOVERED" : "NOT_A_PLAYWRIGHT_REPOSITORY",
|
|
@@ -8008,8 +8008,8 @@ function assertWorkspacePath(root, target, label) {
|
|
|
8008
8008
|
const resolved = path15.resolve(root, target);
|
|
8009
8009
|
if (!fsSync2.existsSync(resolved)) throw new Error(`${label} not found: '${resolved}'`);
|
|
8010
8010
|
const canonicalTarget = fsSync2.realpathSync(resolved);
|
|
8011
|
-
const
|
|
8012
|
-
if (
|
|
8011
|
+
const relative3 = path15.relative(canonicalRoot, canonicalTarget);
|
|
8012
|
+
if (relative3.startsWith("..") || path15.isAbsolute(relative3)) throw new Error(`${label} escapes workspace root: '${target}'`);
|
|
8013
8013
|
return canonicalTarget;
|
|
8014
8014
|
}
|
|
8015
8015
|
function resolveReadOnlyPath(root, target, label) {
|
|
@@ -8198,8 +8198,8 @@ var WorkspacePromoter = class _WorkspacePromoter {
|
|
|
8198
8198
|
}
|
|
8199
8199
|
const canonicalTarget = fs17.realpathSync(targetFilePath);
|
|
8200
8200
|
const canonicalWorkspace = fs17.realpathSync(workspaceRoot);
|
|
8201
|
-
const
|
|
8202
|
-
if (
|
|
8201
|
+
const relative3 = path16.relative(canonicalWorkspace, canonicalTarget);
|
|
8202
|
+
if (relative3.startsWith("..") || path16.isAbsolute(relative3)) {
|
|
8203
8203
|
return {
|
|
8204
8204
|
success: false,
|
|
8205
8205
|
targetFilePath: canonicalTarget,
|
|
@@ -12765,8 +12765,8 @@ async function writeArchitecturePlan(root, plan) {
|
|
|
12765
12765
|
const skipped = [];
|
|
12766
12766
|
for (const file of plan.files) {
|
|
12767
12767
|
const target = path21.resolve(projectRoot, file.relativePath);
|
|
12768
|
-
const
|
|
12769
|
-
if (
|
|
12768
|
+
const relative3 = path21.relative(projectRoot, target);
|
|
12769
|
+
if (relative3.startsWith("..") || path21.isAbsolute(relative3)) throw new Error(`Architecture output path escapes project root: '${file.relativePath}'`);
|
|
12770
12770
|
if (file.action === "SKIP_EXISTING") {
|
|
12771
12771
|
skipped.push(file.relativePath);
|
|
12772
12772
|
continue;
|
|
@@ -14726,8 +14726,8 @@ function assertWorkspacePath2(root, target, label) {
|
|
|
14726
14726
|
const resolved = path25.resolve(root, target);
|
|
14727
14727
|
if (!fsSync4.existsSync(resolved)) throw new Error(`${label} not found: '${resolved}'`);
|
|
14728
14728
|
const canonicalTarget = fsSync4.realpathSync(resolved);
|
|
14729
|
-
const
|
|
14730
|
-
if (
|
|
14729
|
+
const relative3 = path25.relative(canonicalRoot, canonicalTarget);
|
|
14730
|
+
if (relative3.startsWith("..") || path25.isAbsolute(relative3)) throw new Error(`${label} escapes workspace root: '${target}'`);
|
|
14731
14731
|
return canonicalTarget;
|
|
14732
14732
|
}
|
|
14733
14733
|
function resolveReadOnlyPath2(root, target, label) {
|
|
@@ -19055,6 +19055,45 @@ ${generated.specCode}`
|
|
|
19055
19055
|
import * as path31 from "path";
|
|
19056
19056
|
import * as fs31 from "fs";
|
|
19057
19057
|
import { spawn as spawn3, execSync } from "child_process";
|
|
19058
|
+
function findTraceArchives(targetPath) {
|
|
19059
|
+
if (targetPath && !targetPath.startsWith("--")) {
|
|
19060
|
+
const resolved = path31.resolve(targetPath);
|
|
19061
|
+
if (fs31.existsSync(resolved)) {
|
|
19062
|
+
if (fs31.statSync(resolved).isFile() && resolved.endsWith(".zip")) {
|
|
19063
|
+
return [resolved];
|
|
19064
|
+
}
|
|
19065
|
+
}
|
|
19066
|
+
}
|
|
19067
|
+
const candidateDirs = [
|
|
19068
|
+
targetPath && !targetPath.startsWith("--") && fs31.existsSync(targetPath) && fs31.statSync(targetPath).isDirectory() ? path31.resolve(targetPath) : null,
|
|
19069
|
+
path31.resolve("test-results"),
|
|
19070
|
+
path31.resolve("playwright-report"),
|
|
19071
|
+
process.cwd()
|
|
19072
|
+
].filter(Boolean);
|
|
19073
|
+
const found = [];
|
|
19074
|
+
const seen = /* @__PURE__ */ new Set();
|
|
19075
|
+
for (const dir of candidateDirs) {
|
|
19076
|
+
if (!fs31.existsSync(dir)) continue;
|
|
19077
|
+
try {
|
|
19078
|
+
const entries = fs31.readdirSync(dir, { recursive: true });
|
|
19079
|
+
for (const entry of entries) {
|
|
19080
|
+
const fullPath = path31.join(dir, String(entry));
|
|
19081
|
+
if (fullPath.endsWith(".zip") && !seen.has(fullPath)) {
|
|
19082
|
+
try {
|
|
19083
|
+
const stat = fs31.statSync(fullPath);
|
|
19084
|
+
if (stat.isFile()) {
|
|
19085
|
+
seen.add(fullPath);
|
|
19086
|
+
found.push({ filePath: fullPath, mtime: stat.mtimeMs });
|
|
19087
|
+
}
|
|
19088
|
+
} catch {
|
|
19089
|
+
}
|
|
19090
|
+
}
|
|
19091
|
+
}
|
|
19092
|
+
} catch {
|
|
19093
|
+
}
|
|
19094
|
+
}
|
|
19095
|
+
return found.sort((a, b) => b.mtime - a.mtime).map((f) => f.filePath);
|
|
19096
|
+
}
|
|
19058
19097
|
async function runCli(argv) {
|
|
19059
19098
|
const command = argv[2];
|
|
19060
19099
|
if (!command || command === "--help" || command === "-h") {
|
|
@@ -19139,11 +19178,20 @@ async function runCli(argv) {
|
|
|
19139
19178
|
}
|
|
19140
19179
|
}
|
|
19141
19180
|
if (command === "diagnose") {
|
|
19142
|
-
const
|
|
19143
|
-
|
|
19144
|
-
|
|
19181
|
+
const candidateArg = argv[3];
|
|
19182
|
+
const traces = findTraceArchives(candidateArg);
|
|
19183
|
+
if (traces.length === 0) {
|
|
19184
|
+
console.error(
|
|
19185
|
+
"Error: No trace.zip files found in test-results/ or current directory.\nPlease run your Playwright tests with tracing enabled: npx playwright test --trace on\nOr pass the path directly: pw-intel diagnose <path-to-trace.zip>"
|
|
19186
|
+
);
|
|
19145
19187
|
process.exit(1);
|
|
19146
19188
|
}
|
|
19189
|
+
const tracePath = traces[0];
|
|
19190
|
+
if (traces.length > 1) {
|
|
19191
|
+
console.log(`[pw-intel] Auto-discovered ${traces.length} trace files. Diagnosing most recent: ${path31.relative(process.cwd(), tracePath)}`);
|
|
19192
|
+
} else if (!candidateArg || candidateArg.startsWith("--") || fs31.existsSync(candidateArg) && fs31.statSync(candidateArg).isDirectory()) {
|
|
19193
|
+
console.log(`[pw-intel] Auto-discovered trace: ${path31.relative(process.cwd(), tracePath)}`);
|
|
19194
|
+
}
|
|
19147
19195
|
try {
|
|
19148
19196
|
const { traceEntryName, networkEntryName, traceEntryNames, networkEntryNames } = ArchiveReader.findTraceFileEntries(tracePath);
|
|
19149
19197
|
if (!traceEntryName) {
|
|
@@ -19243,11 +19291,20 @@ async function runCli(argv) {
|
|
|
19243
19291
|
return;
|
|
19244
19292
|
}
|
|
19245
19293
|
if (command === "autonomous-repair") {
|
|
19246
|
-
const
|
|
19247
|
-
|
|
19248
|
-
|
|
19294
|
+
const candidateArg = argv[3];
|
|
19295
|
+
const traces = findTraceArchives(candidateArg);
|
|
19296
|
+
if (traces.length === 0) {
|
|
19297
|
+
console.error(
|
|
19298
|
+
"Error: No trace.zip files found in test-results/ or current directory.\nPlease run your Playwright tests with tracing enabled: npx playwright test --trace on\nOr pass the path directly: pw-intel autonomous-repair <trace.zip> [--execute]"
|
|
19299
|
+
);
|
|
19249
19300
|
process.exit(1);
|
|
19250
19301
|
}
|
|
19302
|
+
const tracePath = traces[0];
|
|
19303
|
+
if (traces.length > 1) {
|
|
19304
|
+
console.log(`[pw-intel] Auto-discovered ${traces.length} trace files. Repairing most recent: ${path31.relative(process.cwd(), tracePath)}`);
|
|
19305
|
+
} else if (!candidateArg || candidateArg.startsWith("--") || fs31.existsSync(candidateArg) && fs31.statSync(candidateArg).isDirectory()) {
|
|
19306
|
+
console.log(`[pw-intel] Auto-discovered trace: ${path31.relative(process.cwd(), tracePath)}`);
|
|
19307
|
+
}
|
|
19251
19308
|
try {
|
|
19252
19309
|
const option = (name) => {
|
|
19253
19310
|
const index = argv.indexOf(name);
|