openspec-playwright 0.1.61 ā 0.1.63
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +4 -3
- package/README.zh-CN.md +4 -3
- package/bin/CLAUDE.md +11 -0
- package/dist/CLAUDE.md +17 -0
- package/dist/commands/doctor.d.ts +4 -1
- package/dist/commands/doctor.js +110 -73
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/editors.js +149 -95
- package/dist/commands/editors.js.map +1 -1
- package/dist/commands/init.js +105 -97
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/mcpSync.js +46 -31
- package/dist/commands/mcpSync.js.map +1 -1
- package/dist/commands/run.d.ts +13 -0
- package/dist/commands/run.js +74 -51
- package/dist/commands/run.js.map +1 -1
- package/dist/commands/uninstall.d.ts +1 -0
- package/dist/commands/uninstall.js +133 -0
- package/dist/commands/uninstall.js.map +1 -0
- package/dist/commands/update.d.ts +1 -0
- package/dist/commands/update.js +92 -55
- package/dist/commands/update.js.map +1 -1
- package/dist/index.js +33 -26
- package/dist/index.js.map +1 -1
- package/package.json +19 -1
- package/schemas/playwright-e2e/templates/playwright.config.ts +22 -22
- package/templates/CLAUDE.md +15 -0
- package/templates/seed.spec.ts +5 -3
- package/.claude/commands/opsx/e2e-body.md +0 -39
- package/.claude/commands/opsx/e2e.md +0 -47
- package/.claude/skills/openspec-e2e/SKILL.md +0 -444
- package/.github/workflows/release.yml +0 -81
- package/docs/plans/2026-03-26-openspec-playwright-design.md +0 -180
- package/employee-standards.md +0 -42
- package/openspec/schemas/playwright-e2e/schema.yaml +0 -56
- package/openspec/schemas/playwright-e2e/templates/e2e-test.ts +0 -55
- package/openspec/schemas/playwright-e2e/templates/playwright.config.ts +0 -52
- package/openspec/schemas/playwright-e2e/templates/report.md +0 -27
- package/openspec/schemas/playwright-e2e/templates/test-plan.md +0 -24
- package/openspec-playwright-0.1.61.tgz +0 -0
- package/release-notes.md +0 -5
- package/src/commands/doctor.ts +0 -115
- package/src/commands/editors.ts +0 -606
- package/src/commands/init.ts +0 -252
- package/src/commands/mcpSync.ts +0 -160
- package/src/commands/run.ts +0 -172
- package/src/commands/update.ts +0 -165
- package/src/index.ts +0 -47
- package/tests/editors.test.ts +0 -180
- package/tsconfig.json +0 -18
- package/vitest.config.ts +0 -9
package/dist/commands/init.js
CHANGED
|
@@ -1,182 +1,184 @@
|
|
|
1
|
-
import { execSync } from
|
|
2
|
-
import { existsSync, readFileSync, writeFileSync, mkdirSync
|
|
3
|
-
import { join } from
|
|
4
|
-
import { homedir } from
|
|
5
|
-
import { fileURLToPath } from
|
|
6
|
-
import chalk from
|
|
7
|
-
import { readFile } from
|
|
8
|
-
import { syncMcpTools } from
|
|
9
|
-
import { detectEditors, detectCodex, installForAllEditors, installSkill, installProjectClaudeMd, readEmployeeStandards, claudeAdapter } from
|
|
10
|
-
const TEMPLATE_DIR = fileURLToPath(new URL(
|
|
11
|
-
const SCHEMA_DIR = fileURLToPath(new URL(
|
|
12
|
-
const SKILL_SRC = fileURLToPath(new URL(
|
|
13
|
-
const CMD_BODY_SRC = fileURLToPath(new URL(
|
|
14
|
-
const EMPLOYEE_STANDARDS_SRC = fileURLToPath(new URL(
|
|
1
|
+
import { execSync } from "child_process";
|
|
2
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync } from "fs";
|
|
3
|
+
import { join } from "path";
|
|
4
|
+
import { homedir } from "os";
|
|
5
|
+
import { fileURLToPath } from "url";
|
|
6
|
+
import chalk from "chalk";
|
|
7
|
+
import { readFile } from "fs/promises";
|
|
8
|
+
import { syncMcpTools } from "./mcpSync.js";
|
|
9
|
+
import { detectEditors, detectCodex, installForAllEditors, installSkill, installProjectClaudeMd, readEmployeeStandards, claudeAdapter, } from "./editors.js";
|
|
10
|
+
const TEMPLATE_DIR = fileURLToPath(new URL("../../templates", import.meta.url));
|
|
11
|
+
const SCHEMA_DIR = fileURLToPath(new URL("../../schemas", import.meta.url));
|
|
12
|
+
const SKILL_SRC = fileURLToPath(new URL("../../.claude/skills/openspec-e2e/SKILL.md", import.meta.url));
|
|
13
|
+
const CMD_BODY_SRC = fileURLToPath(new URL("../../.claude/commands/opsx/e2e-body.md", import.meta.url));
|
|
14
|
+
const EMPLOYEE_STANDARDS_SRC = fileURLToPath(new URL("../../employee-standards.md", import.meta.url));
|
|
15
15
|
export async function init(options) {
|
|
16
|
-
console.log(chalk.blue(
|
|
16
|
+
console.log(chalk.blue("\nš§ OpenSpec + Playwright E2E Setup\n"));
|
|
17
17
|
const projectRoot = process.cwd();
|
|
18
18
|
// 1. Check prerequisites
|
|
19
|
-
console.log(chalk.blue(
|
|
20
|
-
const hasNode = execCmd(
|
|
21
|
-
const hasNpm = execCmd(
|
|
22
|
-
|
|
19
|
+
console.log(chalk.blue("āāā Prerequisites āāā"));
|
|
20
|
+
const hasNode = execCmd("node --version", "Node.js", true);
|
|
21
|
+
const hasNpm = execCmd("npm --version", "npm", true);
|
|
22
|
+
execCmd('npx openspec --version 2>/dev/null || echo "not found"', "OpenSpec", true);
|
|
23
23
|
if (!hasNode || !hasNpm) {
|
|
24
|
-
console.log(chalk.red(
|
|
24
|
+
console.log(chalk.red(" ā Node.js/npm is required"));
|
|
25
25
|
process.exit(1);
|
|
26
26
|
}
|
|
27
|
-
console.log(chalk.green(
|
|
27
|
+
console.log(chalk.green(" ā Node.js and npm found"));
|
|
28
28
|
// 2. Check OpenSpec
|
|
29
|
-
if (!existsSync(join(projectRoot,
|
|
30
|
-
console.log(chalk.yellow(
|
|
31
|
-
console.log(chalk.gray(
|
|
32
|
-
console.log(chalk.gray(
|
|
33
|
-
console.log(chalk.gray(
|
|
34
|
-
console.log(chalk.gray(
|
|
35
|
-
console.log(chalk.gray(
|
|
29
|
+
if (!existsSync(join(projectRoot, "openspec"))) {
|
|
30
|
+
console.log(chalk.yellow("\nā OpenSpec not initialized. Run these commands first:"));
|
|
31
|
+
console.log(chalk.gray(" npm install -g @fission-ai/openspec"));
|
|
32
|
+
console.log(chalk.gray(" openspec init"));
|
|
33
|
+
console.log(chalk.gray(" openspec config profile core"));
|
|
34
|
+
console.log(chalk.gray(" openspec update\n"));
|
|
35
|
+
console.log(chalk.gray(" Then run openspec-pw init again.\n"));
|
|
36
36
|
return;
|
|
37
37
|
}
|
|
38
|
-
console.log(chalk.green(
|
|
38
|
+
console.log(chalk.green(" ā OpenSpec initialized"));
|
|
39
39
|
// 3. Install Playwright MCP (global)
|
|
40
40
|
if (options.mcp !== false) {
|
|
41
|
-
console.log(chalk.blue(
|
|
41
|
+
console.log(chalk.blue("\nāāā Installing Playwright MCP āāā"));
|
|
42
42
|
// Check if playwright MCP already exists in global config
|
|
43
|
-
const claudeJsonPath = join(homedir(),
|
|
44
|
-
const claudeJson = existsSync(claudeJsonPath)
|
|
43
|
+
const claudeJsonPath = join(homedir(), ".claude.json");
|
|
44
|
+
const claudeJson = existsSync(claudeJsonPath)
|
|
45
|
+
? JSON.parse(readFileSync(claudeJsonPath, "utf-8"))
|
|
46
|
+
: {};
|
|
45
47
|
const globalMcp = claudeJson?.mcpServers ?? {};
|
|
46
48
|
const localMcp = claudeJson?.projects?.[projectRoot]?.mcpServers ?? {};
|
|
47
|
-
if (globalMcp[
|
|
48
|
-
console.log(chalk.green(
|
|
49
|
+
if (globalMcp["playwright"] || localMcp["playwright"]) {
|
|
50
|
+
console.log(chalk.green(" ā Playwright MCP already installed"));
|
|
49
51
|
}
|
|
50
52
|
else {
|
|
51
53
|
try {
|
|
52
|
-
execSync(
|
|
54
|
+
execSync("claude mcp add playwright npx @playwright/mcp@latest", {
|
|
53
55
|
cwd: projectRoot,
|
|
54
|
-
stdio:
|
|
56
|
+
stdio: "inherit",
|
|
55
57
|
});
|
|
56
|
-
console.log(chalk.green(
|
|
57
|
-
console.log(chalk.gray(
|
|
58
|
+
console.log(chalk.green(" ā Playwright MCP installed globally"));
|
|
59
|
+
console.log(chalk.gray(" (Restart Claude Code to activate)"));
|
|
58
60
|
}
|
|
59
61
|
catch {
|
|
60
|
-
console.log(chalk.yellow(
|
|
61
|
-
console.log(chalk.gray(
|
|
62
|
-
console.log(chalk.gray(
|
|
62
|
+
console.log(chalk.yellow(" ā Failed to run claude mcp add. Run manually:"));
|
|
63
|
+
console.log(chalk.gray(" claude mcp add playwright npx @playwright/mcp@latest"));
|
|
64
|
+
console.log(chalk.gray(" (Restart Claude Code to activate the MCP server)"));
|
|
63
65
|
}
|
|
64
66
|
}
|
|
65
67
|
}
|
|
66
68
|
// 4. Install E2E commands for detected editors
|
|
67
|
-
console.log(chalk.blue(
|
|
69
|
+
console.log(chalk.blue("\nāāā Installing E2E Commands āāā"));
|
|
68
70
|
const detected = detectEditors(projectRoot);
|
|
69
71
|
const codex = detectCodex();
|
|
70
72
|
const adapters = codex ? [...detected, codex] : detected;
|
|
71
73
|
if (adapters.length > 0) {
|
|
72
|
-
const body = await readFile(CMD_BODY_SRC,
|
|
74
|
+
const body = await readFile(CMD_BODY_SRC, "utf-8");
|
|
73
75
|
installForAllEditors(body, adapters, projectRoot);
|
|
74
76
|
}
|
|
75
77
|
else {
|
|
76
|
-
const body = await readFile(CMD_BODY_SRC,
|
|
78
|
+
const body = await readFile(CMD_BODY_SRC, "utf-8");
|
|
77
79
|
installForAllEditors(body, [claudeAdapter], projectRoot);
|
|
78
80
|
}
|
|
79
81
|
// Claude Code also gets the SKILL.md
|
|
80
|
-
if (existsSync(join(projectRoot,
|
|
81
|
-
const skillContent = await readFile(SKILL_SRC,
|
|
82
|
+
if (existsSync(join(projectRoot, ".claude"))) {
|
|
83
|
+
const skillContent = await readFile(SKILL_SRC, "utf-8");
|
|
82
84
|
installSkill(projectRoot, skillContent);
|
|
83
85
|
}
|
|
84
86
|
// 5. Sync Healer tools with latest @playwright/mcp (Claude Code only)
|
|
85
|
-
if (existsSync(join(projectRoot,
|
|
86
|
-
console.log(chalk.blue(
|
|
87
|
-
const skillDest = join(projectRoot,
|
|
87
|
+
if (existsSync(join(projectRoot, ".claude"))) {
|
|
88
|
+
console.log(chalk.blue("\nāāā Syncing Healer Tools āāā"));
|
|
89
|
+
const skillDest = join(projectRoot, ".claude", "skills", "openspec-e2e", "SKILL.md");
|
|
88
90
|
await syncMcpTools(skillDest, true);
|
|
89
91
|
}
|
|
90
92
|
else {
|
|
91
|
-
console.log(chalk.blue(
|
|
92
|
-
console.log(chalk.gray(
|
|
93
|
+
console.log(chalk.blue("\nāāā Syncing Healer Tools āāā"));
|
|
94
|
+
console.log(chalk.gray(" - Claude Code not detected, skipping MCP sync"));
|
|
93
95
|
}
|
|
94
96
|
// 6. Install OpenSpec schema
|
|
95
|
-
console.log(chalk.blue(
|
|
97
|
+
console.log(chalk.blue("\nāāā Installing OpenSpec Schema āāā"));
|
|
96
98
|
await installSchema(projectRoot);
|
|
97
99
|
// 7. Generate seed test
|
|
98
100
|
if (options.seed !== false) {
|
|
99
|
-
console.log(chalk.blue(
|
|
101
|
+
console.log(chalk.blue("\nāāā Generating Seed Test āāā"));
|
|
100
102
|
await generateSeedTest(projectRoot);
|
|
101
103
|
}
|
|
102
104
|
// 8. Generate app-knowledge.md
|
|
103
|
-
console.log(chalk.blue(
|
|
105
|
+
console.log(chalk.blue("\nāāā Generating App Knowledge āāā"));
|
|
104
106
|
await generateAppKnowledge(projectRoot);
|
|
105
107
|
// 9. Install employee-grade CLAUDE.md
|
|
106
|
-
console.log(chalk.blue(
|
|
108
|
+
console.log(chalk.blue("\nāāā Installing Employee Standards āāā"));
|
|
107
109
|
const standards = readEmployeeStandards(EMPLOYEE_STANDARDS_SRC);
|
|
108
110
|
if (standards) {
|
|
109
111
|
installProjectClaudeMd(projectRoot, standards);
|
|
110
112
|
}
|
|
111
113
|
// 10. Summary
|
|
112
|
-
console.log(chalk.blue(
|
|
113
|
-
console.log(chalk.green(
|
|
114
|
-
console.log(chalk.bold(
|
|
115
|
-
console.log(chalk.gray(
|
|
116
|
-
console.log(chalk.gray(
|
|
117
|
-
console.log(chalk.gray(
|
|
118
|
-
console.log(chalk.gray(
|
|
119
|
-
const hasClaude = existsSync(join(projectRoot,
|
|
114
|
+
console.log(chalk.blue("\nāāā Summary āāā"));
|
|
115
|
+
console.log(chalk.green(" ā Setup complete!\n"));
|
|
116
|
+
console.log(chalk.bold("Next steps:"));
|
|
117
|
+
console.log(chalk.gray(" 1. Install Playwright browsers: npx playwright install --with-deps"));
|
|
118
|
+
console.log(chalk.gray(" 2. Customize tests/playwright/credentials.yaml with your test user"));
|
|
119
|
+
console.log(chalk.gray(" 3. Set credentials: export E2E_USERNAME=xxx E2E_PASSWORD=yyy"));
|
|
120
|
+
console.log(chalk.gray(" 4. Run auth setup: npx playwright test --project=setup"));
|
|
121
|
+
const hasClaude = existsSync(join(projectRoot, ".claude"));
|
|
120
122
|
if (hasClaude) {
|
|
121
|
-
console.log(chalk.gray(
|
|
122
|
-
}
|
|
123
|
-
console.log(chalk.gray(` ${hasClaude ?
|
|
124
|
-
console.log(chalk.gray(` ${hasClaude ?
|
|
125
|
-
console.log(chalk.bold(
|
|
126
|
-
console.log(chalk.gray(
|
|
127
|
-
console.log(chalk.gray(
|
|
128
|
-
console.log(chalk.gray(
|
|
123
|
+
console.log(chalk.gray(" 5. In Claude Code, run: /opsx:e2e <change-name>"));
|
|
124
|
+
}
|
|
125
|
+
console.log(chalk.gray(` ${hasClaude ? "6." : "5."} Or: openspec-pw run <change-name>`));
|
|
126
|
+
console.log(chalk.gray(` ${hasClaude ? "7." : "6."} Or: openspec-pw doctor to verify setup\n`));
|
|
127
|
+
console.log(chalk.bold("How it works:"));
|
|
128
|
+
console.log(chalk.gray(" /opsx:e2e reads your OpenSpec specs and runs Playwright"));
|
|
129
|
+
console.log(chalk.gray(" E2E tests through a three-agent pipeline:"));
|
|
130
|
+
console.log(chalk.gray(" Planner ā Generator ā Healer\n"));
|
|
129
131
|
}
|
|
130
132
|
async function generateSeedTest(projectRoot) {
|
|
131
|
-
const testsDir = join(projectRoot,
|
|
133
|
+
const testsDir = join(projectRoot, "tests", "playwright");
|
|
132
134
|
mkdirSync(testsDir, { recursive: true });
|
|
133
|
-
const seedPath = join(testsDir,
|
|
135
|
+
const seedPath = join(testsDir, "seed.spec.ts");
|
|
134
136
|
if (existsSync(seedPath)) {
|
|
135
|
-
console.log(chalk.gray(
|
|
137
|
+
console.log(chalk.gray(" - seed.spec.ts already exists, skipping"));
|
|
136
138
|
}
|
|
137
139
|
else {
|
|
138
|
-
const seedContent = await readFile(TEMPLATE_DIR +
|
|
140
|
+
const seedContent = await readFile(TEMPLATE_DIR + "/seed.spec.ts", "utf-8");
|
|
139
141
|
writeFileSync(seedPath, seedContent);
|
|
140
|
-
console.log(chalk.green(
|
|
142
|
+
console.log(chalk.green(" ā Generated: tests/playwright/seed.spec.ts"));
|
|
141
143
|
}
|
|
142
144
|
// Generate auth.setup.ts
|
|
143
|
-
const authSetupPath = join(testsDir,
|
|
145
|
+
const authSetupPath = join(testsDir, "auth.setup.ts");
|
|
144
146
|
if (existsSync(authSetupPath)) {
|
|
145
|
-
console.log(chalk.gray(
|
|
147
|
+
console.log(chalk.gray(" - auth.setup.ts already exists, skipping"));
|
|
146
148
|
}
|
|
147
149
|
else {
|
|
148
|
-
const authContent = await readFile(TEMPLATE_DIR +
|
|
150
|
+
const authContent = await readFile(TEMPLATE_DIR + "/auth.setup.ts", "utf-8");
|
|
149
151
|
writeFileSync(authSetupPath, authContent);
|
|
150
|
-
console.log(chalk.green(
|
|
152
|
+
console.log(chalk.green(" ā Generated: tests/playwright/auth.setup.ts"));
|
|
151
153
|
}
|
|
152
154
|
// Generate credentials.yaml
|
|
153
|
-
const credsPath = join(testsDir,
|
|
155
|
+
const credsPath = join(testsDir, "credentials.yaml");
|
|
154
156
|
if (existsSync(credsPath)) {
|
|
155
|
-
console.log(chalk.gray(
|
|
157
|
+
console.log(chalk.gray(" - credentials.yaml already exists, skipping"));
|
|
156
158
|
}
|
|
157
159
|
else {
|
|
158
|
-
const credsContent = await readFile(TEMPLATE_DIR +
|
|
160
|
+
const credsContent = await readFile(TEMPLATE_DIR + "/credentials.yaml", "utf-8");
|
|
159
161
|
writeFileSync(credsPath, credsContent);
|
|
160
|
-
console.log(chalk.green(
|
|
162
|
+
console.log(chalk.green(" ā Generated: tests/playwright/credentials.yaml"));
|
|
161
163
|
}
|
|
162
|
-
console.log(chalk.gray(
|
|
164
|
+
console.log(chalk.gray(" (Customize BASE_URL and credentials for your app)"));
|
|
163
165
|
}
|
|
164
166
|
async function generateAppKnowledge(projectRoot) {
|
|
165
|
-
const src = join(SCHEMA_DIR,
|
|
166
|
-
const dest = join(projectRoot,
|
|
167
|
+
const src = join(SCHEMA_DIR, "playwright-e2e", "templates", "app-knowledge.md");
|
|
168
|
+
const dest = join(projectRoot, "tests", "playwright", "app-knowledge.md");
|
|
167
169
|
if (existsSync(dest)) {
|
|
168
|
-
console.log(chalk.gray(
|
|
170
|
+
console.log(chalk.gray(" - app-knowledge.md already exists, skipping"));
|
|
169
171
|
return;
|
|
170
172
|
}
|
|
171
173
|
if (existsSync(src)) {
|
|
172
174
|
writeFileSync(dest, readFileSync(src));
|
|
173
|
-
console.log(chalk.green(
|
|
175
|
+
console.log(chalk.green(" ā Generated: tests/playwright/app-knowledge.md"));
|
|
174
176
|
}
|
|
175
177
|
}
|
|
176
178
|
async function installSchema(projectRoot) {
|
|
177
|
-
const schemaSrc = SCHEMA_DIR +
|
|
178
|
-
const schemaDest = join(projectRoot,
|
|
179
|
-
const schemaFiles = [
|
|
179
|
+
const schemaSrc = SCHEMA_DIR + "/playwright-e2e";
|
|
180
|
+
const schemaDest = join(projectRoot, "openspec", "schemas", "playwright-e2e");
|
|
181
|
+
const schemaFiles = ["schema.yaml"];
|
|
180
182
|
mkdirSync(schemaDest, { recursive: true });
|
|
181
183
|
for (const file of schemaFiles) {
|
|
182
184
|
const src = join(schemaSrc, file);
|
|
@@ -186,10 +188,16 @@ async function installSchema(projectRoot) {
|
|
|
186
188
|
}
|
|
187
189
|
}
|
|
188
190
|
// Copy templates
|
|
189
|
-
const templatesSrc = join(schemaSrc,
|
|
190
|
-
const templatesDest = join(schemaDest,
|
|
191
|
+
const templatesSrc = join(schemaSrc, "templates");
|
|
192
|
+
const templatesDest = join(schemaDest, "templates");
|
|
191
193
|
mkdirSync(templatesDest, { recursive: true });
|
|
192
|
-
const templateFiles = [
|
|
194
|
+
const templateFiles = [
|
|
195
|
+
"test-plan.md",
|
|
196
|
+
"report.md",
|
|
197
|
+
"e2e-test.ts",
|
|
198
|
+
"playwright.config.ts",
|
|
199
|
+
"app-knowledge.md",
|
|
200
|
+
];
|
|
193
201
|
for (const file of templateFiles) {
|
|
194
202
|
const src = join(templatesSrc, file);
|
|
195
203
|
const dest = join(templatesDest, file);
|
|
@@ -197,11 +205,11 @@ async function installSchema(projectRoot) {
|
|
|
197
205
|
writeFileSync(dest, readFileSync(src));
|
|
198
206
|
}
|
|
199
207
|
}
|
|
200
|
-
console.log(chalk.green(
|
|
208
|
+
console.log(chalk.green(" ā Schema installed: openspec/schemas/playwright-e2e/"));
|
|
201
209
|
}
|
|
202
210
|
function execCmd(cmd, name, silent = false) {
|
|
203
211
|
try {
|
|
204
|
-
execSync(cmd, { stdio:
|
|
212
|
+
execSync(cmd, { stdio: "pipe" });
|
|
205
213
|
if (!silent)
|
|
206
214
|
console.log(chalk.green(` ā ${name} found`));
|
|
207
215
|
return true;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/mcpSync.js
CHANGED
|
@@ -1,45 +1,54 @@
|
|
|
1
|
-
import { exec } from
|
|
2
|
-
import { existsSync, readdirSync, readFileSync, writeFileSync, mkdirSync, rmSync } from
|
|
3
|
-
import { join } from
|
|
4
|
-
import { tmpdir } from
|
|
5
|
-
import { promisify } from
|
|
6
|
-
import chalk from
|
|
7
|
-
import * as tar from
|
|
8
|
-
export const MCP_VERSION_MARKER =
|
|
1
|
+
import { exec } from "child_process";
|
|
2
|
+
import { existsSync, readdirSync, readFileSync, writeFileSync, mkdirSync, rmSync, } from "fs";
|
|
3
|
+
import { join } from "path";
|
|
4
|
+
import { tmpdir } from "os";
|
|
5
|
+
import { promisify } from "util";
|
|
6
|
+
import chalk from "chalk";
|
|
7
|
+
import * as tar from "tar";
|
|
8
|
+
export const MCP_VERSION_MARKER = "<!-- MCP_VERSION:";
|
|
9
9
|
export const DEFAULT_HEALER_TOOLS = [
|
|
10
|
-
{ name:
|
|
11
|
-
{
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
10
|
+
{ name: "browser_navigate", purpose: "Go to the failing test's page" },
|
|
11
|
+
{
|
|
12
|
+
name: "browser_snapshot",
|
|
13
|
+
purpose: "Get page structure to find equivalent selectors",
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
name: "browser_console_messages",
|
|
17
|
+
purpose: "Diagnose JS errors that may cause failures",
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
name: "browser_take_screenshot",
|
|
21
|
+
purpose: "Visually compare before/after fixes",
|
|
22
|
+
},
|
|
23
|
+
{ name: "browser_run_code", purpose: "Execute custom fix logic (optional)" },
|
|
15
24
|
];
|
|
16
25
|
/** Extract MCP version from SKILL.md marker */
|
|
17
26
|
export function getStoredMcpVersion(skillContent) {
|
|
18
27
|
const idx = skillContent.indexOf(MCP_VERSION_MARKER);
|
|
19
28
|
if (idx === -1)
|
|
20
29
|
return null;
|
|
21
|
-
const end = skillContent.indexOf(
|
|
30
|
+
const end = skillContent.indexOf(" -->", idx);
|
|
22
31
|
return skillContent.slice(idx + MCP_VERSION_MARKER.length, end).trim();
|
|
23
32
|
}
|
|
24
33
|
/** Remove all existing MCP_VERSION comment lines from content */
|
|
25
34
|
function removeMcpVersionMarkers(content) {
|
|
26
35
|
return content
|
|
27
|
-
.split(
|
|
28
|
-
.filter(line => !line.trim().startsWith(MCP_VERSION_MARKER))
|
|
29
|
-
.join(
|
|
36
|
+
.split("\n")
|
|
37
|
+
.filter((line) => !line.trim().startsWith(MCP_VERSION_MARKER))
|
|
38
|
+
.join("\n");
|
|
30
39
|
}
|
|
31
40
|
/** Build the Healer tools table markdown */
|
|
32
41
|
function buildHealerTable(version, tools) {
|
|
33
|
-
const rows = tools.map(t => `| \`${t.name}\` | ${t.purpose} |`).join(
|
|
42
|
+
const rows = tools.map((t) => `| \`${t.name}\` | ${t.purpose} |`).join("\n");
|
|
34
43
|
return `${MCP_VERSION_MARKER} ${version} -->\n\n| Tool | Purpose |\n|------|---------|\n${rows}`;
|
|
35
44
|
}
|
|
36
45
|
/** Replace the Healer tools table in SKILL.md */
|
|
37
46
|
export function updateHealerTable(skillContent, version, tools) {
|
|
38
47
|
const noMarkers = removeMcpVersionMarkers(skillContent);
|
|
39
|
-
const start = noMarkers.indexOf(
|
|
48
|
+
const start = noMarkers.indexOf("| Tool | Purpose |");
|
|
40
49
|
if (start === -1)
|
|
41
50
|
return skillContent;
|
|
42
|
-
let end = noMarkers.indexOf(
|
|
51
|
+
let end = noMarkers.indexOf("\n\n", start);
|
|
43
52
|
if (end === -1)
|
|
44
53
|
end = noMarkers.length;
|
|
45
54
|
const before = noMarkers.slice(0, start);
|
|
@@ -49,7 +58,7 @@ export function updateHealerTable(skillContent, version, tools) {
|
|
|
49
58
|
/** Fetch latest @playwright/mcp version from npm registry */
|
|
50
59
|
export function getLatestMcpVersion() {
|
|
51
60
|
return new Promise((resolve) => {
|
|
52
|
-
exec(
|
|
61
|
+
exec("npm show @playwright/mcp version --json", { timeout: 15000 }, (err, stdout) => {
|
|
53
62
|
if (err) {
|
|
54
63
|
resolve(null);
|
|
55
64
|
return;
|
|
@@ -77,11 +86,14 @@ function parseMcpReadme(content) {
|
|
|
77
86
|
let m;
|
|
78
87
|
while ((m = re.exec(content)) !== null) {
|
|
79
88
|
const name = m[1].trim();
|
|
80
|
-
if (name.startsWith(
|
|
81
|
-
const purpose = m[2].trim().replace(/\.$/,
|
|
89
|
+
if (name.startsWith("browser_")) {
|
|
90
|
+
const purpose = m[2].trim().replace(/\.$/, "");
|
|
82
91
|
tools.push({ name, purpose });
|
|
83
92
|
}
|
|
84
93
|
}
|
|
94
|
+
if (tools.length === 0) {
|
|
95
|
+
console.error("[openspec-pw] Warning: @playwright/mcp README format changed, no tools parsed. Healer will use default tools.");
|
|
96
|
+
}
|
|
85
97
|
return tools;
|
|
86
98
|
}
|
|
87
99
|
/**
|
|
@@ -92,18 +104,21 @@ export async function fetchMcpTools(version) {
|
|
|
92
104
|
const tmpDir = join(tmpdir(), `openspec-pw-mcp-${version}`);
|
|
93
105
|
try {
|
|
94
106
|
await execAsync(`npm pack @playwright/mcp@${version} --pack-destination ${tmpDir}`, { timeout: 30000 });
|
|
95
|
-
const tgzFiles = readdirSync(tmpDir).filter(f => f.startsWith(
|
|
107
|
+
const tgzFiles = readdirSync(tmpDir).filter((f) => f.startsWith("playwright-mcp-") && f.endsWith(".tgz"));
|
|
96
108
|
if (tgzFiles.length === 0)
|
|
97
109
|
return [];
|
|
98
110
|
const tarballPath = join(tmpDir, tgzFiles[0]);
|
|
99
|
-
const extractDir = join(tmpDir,
|
|
111
|
+
const extractDir = join(tmpDir, "pkg");
|
|
100
112
|
await extractTarball(tarballPath, extractDir);
|
|
101
|
-
const readmePath = join(extractDir,
|
|
102
|
-
const content = existsSync(readmePath)
|
|
113
|
+
const readmePath = join(extractDir, "README.md");
|
|
114
|
+
const content = existsSync(readmePath)
|
|
115
|
+
? readFileSync(readmePath, "utf-8")
|
|
116
|
+
: "";
|
|
103
117
|
rmSync(tmpDir, { recursive: true, force: true });
|
|
104
118
|
return parseMcpReadme(content);
|
|
105
119
|
}
|
|
106
120
|
catch {
|
|
121
|
+
console.log(chalk.yellow(" ā Failed to fetch MCP tools ā using default set"));
|
|
107
122
|
return [];
|
|
108
123
|
}
|
|
109
124
|
}
|
|
@@ -115,15 +130,15 @@ export async function syncMcpTools(skillDest, verbose = false) {
|
|
|
115
130
|
const latestVersion = await getLatestMcpVersion();
|
|
116
131
|
if (!latestVersion) {
|
|
117
132
|
if (verbose)
|
|
118
|
-
console.log(chalk.yellow(
|
|
133
|
+
console.log(chalk.yellow(" ā Could not fetch latest @playwright/mcp version"));
|
|
119
134
|
return false;
|
|
120
135
|
}
|
|
121
136
|
if (!existsSync(skillDest)) {
|
|
122
137
|
if (verbose)
|
|
123
|
-
console.log(chalk.gray(
|
|
138
|
+
console.log(chalk.gray(" - SKILL.md not found, skipping MCP sync"));
|
|
124
139
|
return false;
|
|
125
140
|
}
|
|
126
|
-
const skillContent = readFileSync(skillDest,
|
|
141
|
+
const skillContent = readFileSync(skillDest, "utf-8");
|
|
127
142
|
const storedVersion = getStoredMcpVersion(skillContent);
|
|
128
143
|
if (storedVersion === latestVersion) {
|
|
129
144
|
if (verbose)
|
|
@@ -131,7 +146,7 @@ export async function syncMcpTools(skillDest, verbose = false) {
|
|
|
131
146
|
return false;
|
|
132
147
|
}
|
|
133
148
|
if (verbose)
|
|
134
|
-
console.log(chalk.blue(` - Updating from ${storedVersion ??
|
|
149
|
+
console.log(chalk.blue(` - Updating from ${storedVersion ?? "unknown"} ā ${latestVersion}`));
|
|
135
150
|
const tools = await fetchMcpTools(latestVersion);
|
|
136
151
|
const toolSet = tools.length > 0 ? tools : DEFAULT_HEALER_TOOLS;
|
|
137
152
|
const updated = updateHealerTable(skillContent, latestVersion, toolSet);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcpSync.js","sourceRoot":"","sources":["../../src/commands/mcpSync.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AACrC,OAAO,
|
|
1
|
+
{"version":3,"file":"mcpSync.js","sourceRoot":"","sources":["../../src/commands/mcpSync.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/run.d.ts
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
export interface RunOptions {
|
|
2
2
|
project?: string;
|
|
3
3
|
timeout?: number;
|
|
4
|
+
json?: boolean;
|
|
4
5
|
}
|
|
5
6
|
export declare function run(changeName: string, options: RunOptions): Promise<void>;
|
|
7
|
+
interface TestResults {
|
|
8
|
+
total: number;
|
|
9
|
+
passed: number;
|
|
10
|
+
failed: number;
|
|
11
|
+
duration: string;
|
|
12
|
+
tests: Array<{
|
|
13
|
+
name: string;
|
|
14
|
+
status: "passed" | "failed";
|
|
15
|
+
}>;
|
|
16
|
+
}
|
|
17
|
+
export declare function parsePlaywrightOutput(output: string): TestResults;
|
|
18
|
+
export {};
|