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.
Files changed (48) hide show
  1. package/README.md +229 -229
  2. package/dist/cli/index.d.ts.map +1 -1
  3. package/dist/core/version.d.ts +3 -3
  4. package/dist/index.js +81 -24
  5. package/package.json +76 -76
  6. package/src/authoring/author.ts +81 -81
  7. package/src/authoring/generation-contract.ts +283 -283
  8. package/src/authoring/hybrid-author.ts +115 -115
  9. package/src/authoring/index.ts +7 -7
  10. package/src/authoring/llm-author.ts +282 -282
  11. package/src/authoring/naming/name-plan.ts +28 -28
  12. package/src/authoring/naming/name-planner.ts +339 -339
  13. package/src/authoring/naming/naming-linter.ts +292 -292
  14. package/src/cli/index.ts +1238 -1172
  15. package/src/collectors/git-diff-collector.ts +190 -190
  16. package/src/core/version.ts +25 -25
  17. package/src/diagnostics/diagnostic-report.ts +204 -204
  18. package/src/diagnostics/failure-classifier.ts +701 -701
  19. package/src/evaluation/repository-runner.ts +197 -197
  20. package/src/gate/quality.ts +101 -101
  21. package/src/generator/architecture-generator.ts +582 -582
  22. package/src/generator/assertion-quality-gate.ts +88 -88
  23. package/src/generator/candidate-writer.ts +288 -288
  24. package/src/generator/test-generator.ts +52 -52
  25. package/src/index.ts +107 -107
  26. package/src/intelligence/evidence-bundle.ts +300 -300
  27. package/src/intelligence/generation-agent.ts +561 -561
  28. package/src/intelligence/generation-verifier.ts +1115 -1115
  29. package/src/intelligence/locator-disambiguation-engine.ts +331 -331
  30. package/src/intelligence/project-intelligence.ts +140 -140
  31. package/src/intelligence/repository-profile.ts +796 -796
  32. package/src/intelligence/trace-proposal-workflow.ts +318 -318
  33. package/src/intelligence/workflow-planner.ts +966 -966
  34. package/src/mcp/server.ts +970 -970
  35. package/src/perception/app-model.ts +32 -32
  36. package/src/perception/crawler.ts +263 -263
  37. package/src/perception/index.ts +3 -3
  38. package/src/repair/assertion-hasher.ts +386 -386
  39. package/src/repair/diff-allowlist.ts +612 -612
  40. package/src/repair/intent-validator.ts +761 -761
  41. package/src/repair/repair-planner.ts +467 -467
  42. package/src/repair/statement-patcher.ts +544 -544
  43. package/src/reproduce/interactive-workflow-runner.ts +828 -828
  44. package/src/sandbox/execution-runner.ts +408 -408
  45. package/src/selector/abstention-policy.ts +175 -175
  46. package/src/selector/candidate-extractor.ts +343 -343
  47. package/src/selector/repair-candidate-ranker.ts +92 -92
  48. 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
- [![npm version](https://img.shields.io/npm/v/playwright-intelligence-engine.svg?style=flat-square)](https://www.npmjs.com/package/playwright-intelligence-engine)
6
- [![License](https://img.shields.io/badge/License-Apache--2.0-blue.svg?style=flat-square)](LICENSE)
7
- [![Node](https://img.shields.io/badge/Node->=20.0.0-green.svg?style=flat-square)](https://nodejs.org/)
8
- [![Playwright](https://img.shields.io/badge/Playwright->=1.30-orange.svg?style=flat-square)](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
+ [![npm version](https://img.shields.io/npm/v/playwright-intelligence-engine.svg?style=flat-square)](https://www.npmjs.com/package/playwright-intelligence-engine)
6
+ [![License](https://img.shields.io/badge/License-Apache--2.0-blue.svg?style=flat-square)](LICENSE)
7
+ [![Node](https://img.shields.io/badge/Node->=20.0.0-green.svg?style=flat-square)](https://nodejs.org/)
8
+ [![Playwright](https://img.shields.io/badge/Playwright->=1.30-orange.svg?style=flat-square)](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 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AAuCA,wBAAsB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CA4+B1D"}
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"}
@@ -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.1";
6
- export declare const ENGINE_MILESTONE = "2.0.1";
7
- export declare const PROOF_VERSION = "2.0.1";
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.1";
4
- var ENGINE_MILESTONE = "2.0.1";
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 relative2 = path.relative(resolvedDest, targetFilePath);
362
- if (relative2.startsWith("..") || path.isAbsolute(relative2) || path.win32.isAbsolute(relative2) || path.posix.isAbsolute(relative2)) {
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 relative2 = files.map((file) => path2.relative(absoluteRoot, file));
2120
- const configs = relative2.filter((file) => /(^|[\\/])playwright(?:\.[^.]*)?\.config\.(?:ts|js|mjs|cjs)$/i.test(file));
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: relative2.filter((file) => /(?:^|[\\/])(?:tests?|e2e)(?:[\\/]).*\.(?:spec|test)\.(?:ts|tsx|js|jsx|mjs|cjs)$/i.test(file)).length,
2136
- pageObjectFiles: relative2.filter((file) => /(?:page|pages|pom|page-objects?)[\\/].*\.(?:ts|tsx|js|jsx)$/i.test(file)).length,
2137
- fixtureFiles: relative2.filter((file) => /fixture/i.test(file) && /\.(?:ts|tsx|js|jsx)$/.test(file)).length,
2138
- hasDocker: relative2.some((file) => /(?:^|[\\/])(?:docker-compose[^\\/]*|Dockerfile(?:\..*)?)$/i.test(file)),
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 relative2 = path15.relative(canonicalRoot, canonicalTarget);
8012
- if (relative2.startsWith("..") || path15.isAbsolute(relative2)) throw new Error(`${label} escapes workspace root: '${target}'`);
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 relative2 = path16.relative(canonicalWorkspace, canonicalTarget);
8202
- if (relative2.startsWith("..") || path16.isAbsolute(relative2)) {
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 relative2 = path21.relative(projectRoot, target);
12769
- if (relative2.startsWith("..") || path21.isAbsolute(relative2)) throw new Error(`Architecture output path escapes project root: '${file.relativePath}'`);
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 relative2 = path25.relative(canonicalRoot, canonicalTarget);
14730
- if (relative2.startsWith("..") || path25.isAbsolute(relative2)) throw new Error(`${label} escapes workspace root: '${target}'`);
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 tracePath = argv[3];
19143
- if (!tracePath) {
19144
- console.error("Error: trace.zip path required. Usage: pw-intel diagnose <path-to-trace.zip> [--error-context <error-context.md>]");
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 tracePath = argv[3];
19247
- if (!tracePath) {
19248
- console.error("Error: trace.zip path required. Usage: pw-intel autonomous-repair <trace.zip> [--execute] [--test <spec>] [--pom <page-object>] [--class <Class>] [--member <member>]");
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);