openspec-playwright 0.1.28 → 0.1.29

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.
@@ -7,7 +7,7 @@ compatibility: Requires openspec CLI, Playwright (with browsers installed), and
7
7
  **Architecture**: Uses CLI + SKILLs (not `init-agents`). This follows Playwright's recommended approach for coding agents — CLI is more token-efficient than loading MCP tool schemas into context. MCP is used only for Healer (UI inspection on failure).
8
8
  metadata:
9
9
  author: openspec-playwright
10
- version: "2.3"
10
+ version: "2.4"
11
11
  ---
12
12
 
13
13
  ## Input
@@ -25,6 +25,12 @@ metadata:
25
25
 
26
26
  ## Architecture
27
27
 
28
+ This skill implements the Playwright Test Agents pipeline:
29
+
30
+ - **🎭 Planner** (Step 4): Consumes OpenSpec specs (`specs/*.md`) and produces `test-plan.md` — combines OpenSpec's structured requirements with LLM编排.
31
+ - **🎭 Generator** (Step 5): Transforms the Markdown test-plan into real Playwright `.spec.ts` files using LLM code generation.
32
+ - **🎭 Healer** (Step 8): Executes the test suite and automatically repairs failing selectors via Playwright MCP tools.
33
+
28
34
  Uses CLI + SKILLs (not `init-agents`). This follows Playwright's recommended approach for coding agents — CLI is more token-efficient than loading MCP tool schemas into context. MCP is used only for Healer (UI inspection on failure).
29
35
 
30
36
  **Schema owns templates. CLI handles execution. Skill handles cognitive work.**
@@ -63,7 +69,24 @@ Detect if auth is required. Mark as **auth required** only when BOTH conditions
63
69
  - Medium (proceed with note): Single explicit marker, context unclear
64
70
  - Low (skip auth): No explicit markers found
65
71
 
66
- ### 3. Generate test plan
72
+ ### 3. Validate environment
73
+
74
+ Before generating tests, verify the environment is ready by running the seed test:
75
+
76
+ ```bash
77
+ npx playwright test tests/playwright/seed.spec.ts --project=chromium
78
+ ```
79
+
80
+ **What this validates**:
81
+ - App server is reachable (BASE_URL accessible)
82
+ - Auth fixtures (`storageState`) are initialized if auth is required
83
+ - Playwright browser and config are working
84
+
85
+ **If seed test fails**: Stop and report the failure. User must fix the environment before proceeding.
86
+
87
+ **If seed test passes or no auth required**: Proceed to Step 4.
88
+
89
+ ### 4. Generate test plan
67
90
 
68
91
  Create `openspec/changes/<name>/specs/playwright/test-plan.md` by:
69
92
  - Listing each functional requirement as a test case
@@ -73,7 +96,7 @@ Create `openspec/changes/<name>/specs/playwright/test-plan.md` by:
73
96
 
74
97
  **Idempotency**: If test-plan.md already exists → read it, use it, do NOT regenerate unless user explicitly asks.
75
98
 
76
- ### 4. Generate test file (LLM-driven)
99
+ ### 5. Generate test file (LLM-driven)
77
100
 
78
101
  Use your file writing capability to create `tests/playwright/<name>.spec.ts`.
79
102
 
@@ -115,7 +138,7 @@ test.describe('Feature Name', () => {
115
138
 
116
139
  **Selector guidance**: If no `data-testid` exists in the app, prefer `getByRole`, `getByLabel`, `getByText` over fragile selectors like CSS paths.
117
140
 
118
- ### 5. Configure auth (if required)
141
+ ### 6. Configure auth (if required)
119
142
 
120
143
  If auth is required:
121
144
 
@@ -137,7 +160,7 @@ Auth required. To set up credentials:
137
160
 
138
161
  **Idempotency**: If `auth.setup.ts` already exists → verify format, update only if stale.
139
162
 
140
- ### 6. Configure playwright.config.ts (non-destructive)
163
+ ### 7. Configure playwright.config.ts (non-destructive)
141
164
 
142
165
  If `playwright.config.ts` does not exist → generate it from the schema template at `openspec/schemas/playwright-e2e/templates/playwright.config.ts`. The template auto-detects:
143
166
  - **BASE_URL**: from `process.env.BASE_URL`, falling back to `tests/playwright/seed.spec.ts` → `BASE_URL` value, then `http://localhost:3000`
@@ -145,7 +168,7 @@ If `playwright.config.ts` does not exist → generate it from the schema templat
145
168
 
146
169
  If `playwright.config.ts` exists → READ it first. Extract existing `webServer`, `use.baseURL`, and `projects`. Preserve ALL existing fields. Add `webServer` block if missing. Do NOT replace existing config values.
147
170
 
148
- ### 7. Execute tests via CLI
171
+ ### 8. Execute tests via CLI
149
172
 
150
173
  ```bash
151
174
  openspec-pw run <name> --project=<role>
@@ -160,19 +183,20 @@ The CLI handles:
160
183
  If tests fail → analyze failures, use **Playwright MCP tools** to inspect UI state, fix selectors in the test file, and re-run.
161
184
 
162
185
  **Healer MCP tools** (in order of use):
186
+ <!-- MCP_VERSION: 0.0.68 -->
163
187
 
164
188
  | Tool | Purpose |
165
189
  |------|---------|
166
- | `Navigate to a URL` | Go to the failing test's page |
167
- | `Page snapshot` | Get page structure to find equivalent selectors |
168
- | `Get console messages` | Diagnose JS errors that may cause failures |
169
- | `Take a screenshot` | Visually compare before/after fixes |
170
- | `Run Playwright code` | Execute custom fix logic (optional) |
190
+ | `browser_navigate` | Go to the failing test's page |
191
+ | `browser_snapshot` | Get page structure to find equivalent selectors |
192
+ | `browser_console_messages` | Diagnose JS errors that may cause failures |
193
+ | `browser_take_screenshot` | Visually compare before/after fixes |
194
+ | `browser_run_code` | Execute custom fix logic (optional) |
171
195
 
172
196
  **Healer workflow**:
173
197
  1. Read the failing test file — identify the broken selector or assertion
174
- 2. Navigate to the target page with `Navigate to a URL`
175
- 3. Take a `Page snapshot` — find an equivalent stable selector
198
+ 2. Navigate to the target page with `browser_navigate`
199
+ 3. Take a `browser_snapshot` — find an equivalent stable selector
176
200
  4. Fix the selector in the test file using the Edit tool
177
201
  5. Re-run: `openspec-pw run <name>`
178
202
  6. Repeat until pass or 3 attempts reached
@@ -181,7 +205,7 @@ If tests fail → analyze failures, use **Playwright MCP tools** to inspect UI s
181
205
 
182
206
  **Cap auto-heal attempts at 3** to prevent infinite loops.
183
207
 
184
- ### 8. Report results
208
+ ### 9. Report results
185
209
 
186
210
  Read the report at `openspec/reports/playwright-e2e-<name>-<timestamp>.md`.
187
211
 
@@ -238,6 +262,7 @@ Read the report at `openspec/reports/playwright-e2e-<name>-<timestamp>.md`.
238
262
  | Scenario | Behavior |
239
263
  |----------|----------|
240
264
  | No specs found | Stop with info message — E2E requires specs |
265
+ | Seed test fails | Stop with failure — fix environment before proceeding |
241
266
  | No auth required | Skip auth setup entirely |
242
267
  | test-plan.md exists | Read and use it — never regenerate |
243
268
  | auth.setup.ts exists | Verify format — update only if stale |
@@ -3,6 +3,7 @@ import { existsSync, readFileSync, writeFileSync, mkdirSync, } from 'fs';
3
3
  import { join } from 'path';
4
4
  import chalk from 'chalk';
5
5
  import { readFile } from 'fs/promises';
6
+ import { syncMcpTools } from './mcpSync.js';
6
7
  const TEMPLATE_DIR = new URL('../../templates', import.meta.url).pathname;
7
8
  const SCHEMA_DIR = new URL('../../schemas', import.meta.url).pathname;
8
9
  const SKILL_SRC = new URL('../../.claude/skills/openspec-e2e', import.meta.url).pathname;
@@ -61,15 +62,19 @@ export async function init(options) {
61
62
  // 4. Copy skill files
62
63
  console.log(chalk.blue('\n─── Installing Claude Code Skill ───'));
63
64
  await installSkill(projectRoot);
64
- // 5. Install OpenSpec schema
65
+ // 5. Sync Healer tools with latest @playwright/mcp
66
+ console.log(chalk.blue('\n─── Syncing Healer Tools ───'));
67
+ const skillDest = join(projectRoot, '.claude', 'skills', 'openspec-e2e', 'SKILL.md');
68
+ await syncMcpTools(skillDest, true);
69
+ // 6. Install OpenSpec schema
65
70
  console.log(chalk.blue('\n─── Installing OpenSpec Schema ───'));
66
71
  await installSchema(projectRoot);
67
- // 6. Generate seed test
72
+ // 7. Generate seed test
68
73
  if (options.seed !== false) {
69
74
  console.log(chalk.blue('\n─── Generating Seed Test ───'));
70
75
  await generateSeedTest(projectRoot);
71
76
  }
72
- // 7. Summary
77
+ // 8. Summary
73
78
  console.log(chalk.blue('\n─── Summary ───'));
74
79
  console.log(chalk.green(' ✓ Setup complete!\n'));
75
80
  console.log(chalk.bold('Next steps:'));
@@ -1 +1 @@
1
- {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ export declare const MCP_VERSION_MARKER = "<!-- MCP_VERSION:";
2
+ export declare const DEFAULT_HEALER_TOOLS: {
3
+ name: string;
4
+ purpose: string;
5
+ }[];
6
+ /** Extract MCP version from SKILL.md marker */
7
+ export declare function getStoredMcpVersion(skillContent: string): string | null;
8
+ /** Replace the Healer tools table in SKILL.md */
9
+ export declare function updateHealerTable(skillContent: string, version: string, tools: Array<{
10
+ name: string;
11
+ purpose: string;
12
+ }>): string;
13
+ /** Fetch latest @playwright/mcp version from npm registry */
14
+ export declare function getLatestMcpVersion(): Promise<string | null>;
15
+ /**
16
+ * Fetch @playwright/mcp tools from npm package.
17
+ * Downloads the tarball, extracts README, parses tool names.
18
+ */
19
+ export declare function fetchMcpTools(version: string): Promise<Array<{
20
+ name: string;
21
+ purpose: string;
22
+ }>>;
23
+ /**
24
+ * Sync Healer tools table in SKILL.md with latest @playwright/mcp.
25
+ * Returns true if updated, false if already current or failed.
26
+ */
27
+ export declare function syncMcpTools(skillDest: string, verbose?: boolean): Promise<boolean>;
@@ -0,0 +1,124 @@
1
+ import { exec } from 'child_process';
2
+ import { existsSync, readFileSync, writeFileSync } from 'fs';
3
+ import chalk from 'chalk';
4
+ export const MCP_VERSION_MARKER = '<!-- MCP_VERSION:';
5
+ export const DEFAULT_HEALER_TOOLS = [
6
+ { name: 'browser_navigate', purpose: "Go to the failing test's page" },
7
+ { name: 'browser_snapshot', purpose: 'Get page structure to find equivalent selectors' },
8
+ { name: 'browser_console_messages', purpose: 'Diagnose JS errors that may cause failures' },
9
+ { name: 'browser_take_screenshot', purpose: 'Visually compare before/after fixes' },
10
+ { name: 'browser_run_code', purpose: 'Execute custom fix logic (optional)' },
11
+ ];
12
+ /** Extract MCP version from SKILL.md marker */
13
+ export function getStoredMcpVersion(skillContent) {
14
+ const idx = skillContent.indexOf(MCP_VERSION_MARKER);
15
+ if (idx === -1)
16
+ return null;
17
+ const end = skillContent.indexOf(' -->', idx);
18
+ return skillContent.slice(idx + MCP_VERSION_MARKER.length, end).trim();
19
+ }
20
+ /** Build the Healer tools table markdown */
21
+ function buildHealerTable(version, tools) {
22
+ const rows = tools.map(t => `| \`${t.name}\` | ${t.purpose} |`).join('\n');
23
+ return `${MCP_VERSION_MARKER} ${version} -->\n\n| Tool | Purpose |\n|------|---------|\n${rows}`;
24
+ }
25
+ /** Replace the Healer tools table in SKILL.md */
26
+ export function updateHealerTable(skillContent, version, tools) {
27
+ const start = skillContent.indexOf('| Tool | Purpose |');
28
+ if (start === -1)
29
+ return skillContent;
30
+ let end = skillContent.indexOf('\n\n', start);
31
+ if (end === -1)
32
+ end = skillContent.length;
33
+ const before = skillContent.slice(0, start);
34
+ const after = skillContent.slice(end);
35
+ return before + buildHealerTable(version, tools) + after;
36
+ }
37
+ /** Fetch latest @playwright/mcp version from npm registry */
38
+ export function getLatestMcpVersion() {
39
+ return new Promise((resolve) => {
40
+ exec('npm show @playwright/mcp version --json', { timeout: 15000 }, (err, stdout) => {
41
+ if (err) {
42
+ resolve(null);
43
+ return;
44
+ }
45
+ try {
46
+ resolve(JSON.parse(stdout.trim()));
47
+ }
48
+ catch {
49
+ resolve(null);
50
+ }
51
+ });
52
+ });
53
+ }
54
+ /** Parse README markdown to extract browser_* tool entries */
55
+ function parseMcpReadme(content) {
56
+ const tools = [];
57
+ const re = /-\s+\*\*`?([^`*\n]+)`?\*\*\s*-\s*Title:\s*([^\n]+)/g;
58
+ let m;
59
+ while ((m = re.exec(content)) !== null) {
60
+ const name = m[1].trim();
61
+ if (name.startsWith('browser_')) {
62
+ const purpose = m[2].trim().replace(/\.$/, '');
63
+ tools.push({ name, purpose });
64
+ }
65
+ }
66
+ return tools;
67
+ }
68
+ /**
69
+ * Fetch @playwright/mcp tools from npm package.
70
+ * Downloads the tarball, extracts README, parses tool names.
71
+ */
72
+ export function fetchMcpTools(version) {
73
+ return new Promise((resolve) => {
74
+ const tmpDir = `/tmp/openspec-pw-mcp-${version}`;
75
+ exec(`rm -rf ${tmpDir} && mkdir -p ${tmpDir} && npm pack @playwright/mcp@${version} --pack-destination ${tmpDir} 2>/dev/null && tar -xzf ${tmpDir}/playwright-mcp-${version}.tgz -C ${tmpDir} --strip-components=1 && cat ${tmpDir}/package/README.md`, { timeout: 30000 }, (err, stdout) => {
76
+ if (err) {
77
+ resolve([]);
78
+ return;
79
+ }
80
+ const tools = parseMcpReadme(stdout);
81
+ resolve(tools);
82
+ });
83
+ });
84
+ }
85
+ /**
86
+ * Sync Healer tools table in SKILL.md with latest @playwright/mcp.
87
+ * Returns true if updated, false if already current or failed.
88
+ */
89
+ export async function syncMcpTools(skillDest, verbose = false) {
90
+ const latestVersion = await getLatestMcpVersion();
91
+ if (!latestVersion) {
92
+ if (verbose)
93
+ console.log(chalk.yellow(' âš  Could not fetch latest @playwright/mcp version'));
94
+ return false;
95
+ }
96
+ if (!existsSync(skillDest)) {
97
+ if (verbose)
98
+ console.log(chalk.gray(' - SKILL.md not found, skipping MCP sync'));
99
+ return false;
100
+ }
101
+ const skillContent = readFileSync(skillDest, 'utf-8');
102
+ const storedVersion = getStoredMcpVersion(skillContent);
103
+ if (storedVersion === latestVersion) {
104
+ if (verbose)
105
+ console.log(chalk.gray(` - Healer tools current (${latestVersion})`));
106
+ return false;
107
+ }
108
+ if (verbose)
109
+ console.log(chalk.blue(` - Updating from ${storedVersion ?? 'unknown'} → ${latestVersion}`));
110
+ const tools = await fetchMcpTools(latestVersion);
111
+ const toolSet = tools.length > 0 ? tools : DEFAULT_HEALER_TOOLS;
112
+ const updated = updateHealerTable(skillContent, latestVersion, toolSet);
113
+ writeFileSync(skillDest, updated);
114
+ if (verbose) {
115
+ if (tools.length > 0) {
116
+ console.log(chalk.green(` ✓ Healer tools synced to ${latestVersion} (${tools.length} tools)`));
117
+ }
118
+ else {
119
+ console.log(chalk.green(` ✓ Healer tools synced to ${latestVersion} (default set)`));
120
+ }
121
+ }
122
+ return true;
123
+ }
124
+ //# sourceMappingURL=mcpSync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcpSync.js","sourceRoot":"","sources":["../../src/commands/mcpSync.ts"],"names":[],"mappings":"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"}
@@ -2,6 +2,7 @@ import { execSync } from 'child_process';
2
2
  import { existsSync, readFileSync, writeFileSync, mkdirSync, } from 'fs';
3
3
  import { join } from 'path';
4
4
  import chalk from 'chalk';
5
+ import { syncMcpTools } from './mcpSync.js';
5
6
  const SKILL_SRC = new URL('../../.claude/skills/openspec-e2e', import.meta.url).pathname;
6
7
  const CMD_SRC = new URL('../../.claude/commands/opsx', import.meta.url).pathname;
7
8
  const SCHEMA_DIR = new URL('../../schemas', import.meta.url).pathname;
@@ -24,12 +25,10 @@ export async function update(options) {
24
25
  if (options.skill !== false) {
25
26
  console.log(chalk.blue('\n─── Updating Skill & Command ───'));
26
27
  try {
27
- // Download npm tarball and extract
28
28
  const tmpDir = '/tmp/openspec-e2e-update';
29
29
  execSync(`rm -rf ${tmpDir} && mkdir -p ${tmpDir}`, { stdio: 'pipe', cwd: projectRoot });
30
30
  execSync(`npm pack openspec-playwright --pack-destination ${tmpDir}`, { stdio: 'pipe', cwd: projectRoot });
31
31
  const tarball = execSync(`ls -t ${tmpDir}/openspec-playwright-*.tgz | head -1`, { encoding: 'utf-8', cwd: projectRoot }).trim();
32
- // Move tarball out before extracting to avoid "overwrite archive" error
33
32
  const tmpTarball = `${tmpDir}/package.tgz`;
34
33
  execSync(`mv "${tarball}" "${tmpTarball}"`, { stdio: 'pipe', cwd: projectRoot });
35
34
  execSync(`tar -xzf "${tmpTarball}" -C ${tmpDir} --strip-components=1`, { stdio: 'pipe', cwd: projectRoot });
@@ -45,6 +44,10 @@ export async function update(options) {
45
44
  installSkill(projectRoot);
46
45
  }
47
46
  }
47
+ // 3. Sync Healer tools with latest @playwright/mcp
48
+ console.log(chalk.blue('\n─── Syncing Healer Tools ───'));
49
+ const skillDest = join(projectRoot, '.claude', 'skills', 'openspec-e2e', 'SKILL.md');
50
+ await syncMcpTools(skillDest, true);
48
51
  // Summary
49
52
  console.log(chalk.blue('\n─── Summary ───'));
50
53
  console.log(chalk.green(' ✓ Update complete!\n'));
@@ -70,12 +73,10 @@ function installSkillFrom(skillSrc, cmdSrc, schemaSrc, projectRoot) {
70
73
  function installSchemaFrom(schemaSrc, projectRoot) {
71
74
  const schemaDest = join(projectRoot, 'openspec', 'schemas', 'playwright-e2e');
72
75
  mkdirSync(schemaDest, { recursive: true });
73
- // Copy schema.yaml
74
76
  const schemaYamlSrc = join(schemaSrc, 'schema.yaml');
75
77
  if (existsSync(schemaYamlSrc)) {
76
78
  writeFileSync(join(schemaDest, 'schema.yaml'), readFileSync(schemaYamlSrc));
77
79
  }
78
- // Copy templates
79
80
  const templatesSrc = join(schemaSrc, 'templates');
80
81
  const templatesDest = join(schemaDest, 'templates');
81
82
  if (existsSync(templatesSrc)) {
@@ -1 +1 @@
1
- {"version":3,"file":"update.js","sourceRoot":"","sources":["../../src/commands/update.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EACL,UAAU,EACV,YAAY,EACZ,aAAa,EACb,SAAS,GACV,MAAM,IAAI,CAAC;AACZ,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,mCAAmC,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC;AACzF,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,6BAA6B,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC;AACjF,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,eAAe,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC;AAOtE,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,OAAsB;IACjD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,2CAA2C,CAAC,CAAC,CAAC;IAErE,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAElC,8BAA8B;IAC9B,IAAI,OAAO,CAAC,GAAG,KAAK,KAAK,EAAE,CAAC;QAC1B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC,CAAC;QAChD,IAAI,CAAC;YACH,QAAQ,CACN,oCAAoC,EACpC,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,EAAE,WAAW,EAAE,CACvC,CAAC;YACF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC,CAAC;QACtD,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,kCAAkC,CAAC,CAAC,CAAC;YAC9D,OAAO,CAAC,GAAG,CACT,KAAK,CAAC,IAAI,CAAC,oDAAoD,CAAC,CACjE,CAAC;QACJ,CAAC;IACH,CAAC;IAED,+CAA+C;IAC/C,IAAI,OAAO,CAAC,KAAK,KAAK,KAAK,EAAE,CAAC;QAC5B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,oCAAoC,CAAC,CAAC,CAAC;QAC9D,IAAI,CAAC;YACH,mCAAmC;YACnC,MAAM,MAAM,GAAG,0BAA0B,CAAC;YAC1C,QAAQ,CAAC,UAAU,MAAM,gBAAgB,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,WAAW,EAAE,CAAC,CAAC;YACxF,QAAQ,CACN,mDAAmD,MAAM,EAAE,EAC3D,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,WAAW,EAAE,CACpC,CAAC;YACF,MAAM,OAAO,GAAG,QAAQ,CACtB,SAAS,MAAM,sCAAsC,EACrD,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,EAAE,WAAW,EAAE,CACxC,CAAC,IAAI,EAAE,CAAC;YACT,wEAAwE;YACxE,MAAM,UAAU,GAAG,GAAG,MAAM,cAAc,CAAC;YAC3C,QAAQ,CAAC,OAAO,OAAO,MAAM,UAAU,GAAG,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,WAAW,EAAE,CAAC,CAAC;YACjF,QAAQ,CAAC,aAAa,UAAU,QAAQ,MAAM,uBAAuB,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,WAAW,EAAE,CAAC,CAAC;YAE5G,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,cAAc,EAAE,UAAU,CAAC,CAAC;YAC/E,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;YACrE,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,EAAE,SAAS,EAAE,gBAAgB,CAAC,CAAC;YAE5D,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC;YAC3D,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,uCAAuC,CAAC,CAAC,CAAC;QACpE,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,6CAA6C,CAAC,CAAC,CAAC;YACzE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,kCAAkC,CAAC,CAAC,CAAC;YAC5D,YAAY,CAAC,WAAW,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC;IAED,UAAU;IACV,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC;IAC7C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC,CAAC;IAEnD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,+CAA+C,CAAC,CAAC,CAAC;IACzE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,iDAAiD,CAAC,CAAC,CAAC;AAC7E,CAAC;AAED,SAAS,YAAY,CAAC,WAAmB;IACvC,gBAAgB,CACd,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC,EAC3B,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,EACvB,IAAI,CAAC,UAAU,EAAE,gBAAgB,CAAC,EAClC,WAAW,CACZ,CAAC;AACJ,CAAC;AAED,SAAS,gBAAgB,CAAC,QAAgB,EAAE,MAAc,EAAE,SAAiB,EAAE,WAAmB;IAChG,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,cAAc,CAAC,CAAC;IACxE,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;IAExD,SAAS,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACzC,MAAM,YAAY,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACrD,aAAa,CAAC,IAAI,CAAC,QAAQ,EAAE,UAAU,CAAC,EAAE,YAAY,CAAC,CAAC;IACxD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,kCAAkC,CAAC,CAAC,CAAC;IAE7D,SAAS,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACrD,MAAM,UAAU,GAAG,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjD,aAAa,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,UAAU,CAAC,CAAC;IAC1D,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,gCAAgC,CAAC,CAAC,CAAC;IAE3D,iBAAiB,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;AAC5C,CAAC;AAED,SAAS,iBAAiB,CAAC,SAAiB,EAAE,WAAmB;IAC/D,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,EAAE,UAAU,EAAE,SAAS,EAAE,gBAAgB,CAAC,CAAC;IAE9E,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3C,mBAAmB;IACnB,MAAM,aAAa,GAAG,IAAI,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;IACrD,IAAI,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;QAC9B,aAAa,CAAC,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,EAAE,YAAY,CAAC,aAAa,CAAC,CAAC,CAAC;IAC9E,CAAC;IAED,iBAAiB;IACjB,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;IAClD,MAAM,aAAa,GAAG,IAAI,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;IACpD,IAAI,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QAC7B,SAAS,CAAC,aAAa,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC9C,MAAM,aAAa,GAAG,CAAC,cAAc,EAAE,WAAW,EAAE,aAAa,EAAE,sBAAsB,CAAC,CAAC;QAC3F,KAAK,MAAM,IAAI,IAAI,aAAa,EAAE,CAAC;YACjC,MAAM,GAAG,GAAG,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;YACrC,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;YACvC,IAAI,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;gBACpB,aAAa,CAAC,IAAI,EAAE,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC;YACzC,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,sDAAsD,CAAC,CAAC,CAAC;AACnF,CAAC"}
1
+ {"version":3,"file":"update.js","sourceRoot":"","sources":["../../src/commands/update.ts"],"names":[],"mappings":"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"}
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openspec-playwright",
3
- "version": "0.1.28",
3
+ "version": "0.1.29",
4
4
  "description": "OpenSpec + Playwright E2E verification setup tool for Claude Code",
5
5
  "type": "module",
6
6
  "bin": {
package/release-notes.md CHANGED
@@ -1,5 +1,5 @@
1
1
  ## What's Changed
2
2
 
3
- - feat(skill): align SKILL.md with OpenSpec format (v2.3)
3
+ - feat: add MCP version sync for Healer tools (init + update)
4
4
 
5
- **Full Changelog**: https://github.com/wxhou/openspec-playwright/releases/tag/v0.1.28
5
+ **Full Changelog**: https://github.com/wxhou/openspec-playwright/releases/tag/v0.1.29
@@ -8,6 +8,7 @@ import {
8
8
  import { join } from 'path';
9
9
  import chalk from 'chalk';
10
10
  import { readFile } from 'fs/promises';
11
+ import { syncMcpTools } from './mcpSync.js';
11
12
 
12
13
  const TEMPLATE_DIR = new URL('../../templates', import.meta.url).pathname;
13
14
  const SCHEMA_DIR = new URL('../../schemas', import.meta.url).pathname;
@@ -82,17 +83,22 @@ export async function init(options: InitOptions) {
82
83
  console.log(chalk.blue('\n─── Installing Claude Code Skill ───'));
83
84
  await installSkill(projectRoot);
84
85
 
85
- // 5. Install OpenSpec schema
86
+ // 5. Sync Healer tools with latest @playwright/mcp
87
+ console.log(chalk.blue('\n─── Syncing Healer Tools ───'));
88
+ const skillDest = join(projectRoot, '.claude', 'skills', 'openspec-e2e', 'SKILL.md');
89
+ await syncMcpTools(skillDest, true);
90
+
91
+ // 6. Install OpenSpec schema
86
92
  console.log(chalk.blue('\n─── Installing OpenSpec Schema ───'));
87
93
  await installSchema(projectRoot);
88
94
 
89
- // 6. Generate seed test
95
+ // 7. Generate seed test
90
96
  if (options.seed !== false) {
91
97
  console.log(chalk.blue('\n─── Generating Seed Test ───'));
92
98
  await generateSeedTest(projectRoot);
93
99
  }
94
100
 
95
- // 7. Summary
101
+ // 8. Summary
96
102
  console.log(chalk.blue('\n─── Summary ───'));
97
103
  console.log(chalk.green(' ✓ Setup complete!\n'));
98
104
 
@@ -0,0 +1,133 @@
1
+ import { exec } from 'child_process';
2
+ import { existsSync, readFileSync, writeFileSync } from 'fs';
3
+ import { join } from 'path';
4
+ import chalk from 'chalk';
5
+
6
+ export const MCP_VERSION_MARKER = '<!-- MCP_VERSION:';
7
+
8
+ export const DEFAULT_HEALER_TOOLS = [
9
+ { name: 'browser_navigate', purpose: "Go to the failing test's page" },
10
+ { name: 'browser_snapshot', purpose: 'Get page structure to find equivalent selectors' },
11
+ { name: 'browser_console_messages', purpose: 'Diagnose JS errors that may cause failures' },
12
+ { name: 'browser_take_screenshot', purpose: 'Visually compare before/after fixes' },
13
+ { name: 'browser_run_code', purpose: 'Execute custom fix logic (optional)' },
14
+ ];
15
+
16
+ /** Extract MCP version from SKILL.md marker */
17
+ export function getStoredMcpVersion(skillContent: string): string | null {
18
+ const idx = skillContent.indexOf(MCP_VERSION_MARKER);
19
+ if (idx === -1) return null;
20
+ const end = skillContent.indexOf(' -->', idx);
21
+ return skillContent.slice(idx + MCP_VERSION_MARKER.length, end).trim();
22
+ }
23
+
24
+ /** Build the Healer tools table markdown */
25
+ function buildHealerTable(version: string, tools: Array<{ name: string; purpose: string }>): string {
26
+ const rows = tools.map(t => `| \`${t.name}\` | ${t.purpose} |`).join('\n');
27
+ return `${MCP_VERSION_MARKER} ${version} -->\n\n| Tool | Purpose |\n|------|---------|\n${rows}`;
28
+ }
29
+
30
+ /** Replace the Healer tools table in SKILL.md */
31
+ export function updateHealerTable(
32
+ skillContent: string,
33
+ version: string,
34
+ tools: Array<{ name: string; purpose: string }>
35
+ ): string {
36
+ const start = skillContent.indexOf('| Tool | Purpose |');
37
+ if (start === -1) return skillContent;
38
+ let end = skillContent.indexOf('\n\n', start);
39
+ if (end === -1) end = skillContent.length;
40
+
41
+ const before = skillContent.slice(0, start);
42
+ const after = skillContent.slice(end);
43
+ return before + buildHealerTable(version, tools) + after;
44
+ }
45
+
46
+ /** Fetch latest @playwright/mcp version from npm registry */
47
+ export function getLatestMcpVersion(): Promise<string | null> {
48
+ return new Promise((resolve) => {
49
+ exec('npm show @playwright/mcp version --json', { timeout: 15000 }, (err, stdout) => {
50
+ if (err) { resolve(null); return; }
51
+ try { resolve(JSON.parse(stdout.trim())); } catch { resolve(null); }
52
+ });
53
+ });
54
+ }
55
+
56
+ /** Parse README markdown to extract browser_* tool entries */
57
+ function parseMcpReadme(content: string): Array<{ name: string; purpose: string }> {
58
+ const tools: Array<{ name: string; purpose: string }> = [];
59
+ const re = /-\s+\*\*`?([^`*\n]+)`?\*\*\s*-\s*Title:\s*([^\n]+)/g;
60
+ let m;
61
+ while ((m = re.exec(content)) !== null) {
62
+ const name = m[1].trim();
63
+ if (name.startsWith('browser_')) {
64
+ const purpose = m[2].trim().replace(/\.$/, '');
65
+ tools.push({ name, purpose });
66
+ }
67
+ }
68
+ return tools;
69
+ }
70
+
71
+ /**
72
+ * Fetch @playwright/mcp tools from npm package.
73
+ * Downloads the tarball, extracts README, parses tool names.
74
+ */
75
+ export function fetchMcpTools(version: string): Promise<Array<{ name: string; purpose: string }>> {
76
+ return new Promise((resolve) => {
77
+ const tmpDir = `/tmp/openspec-pw-mcp-${version}`;
78
+ exec(
79
+ `rm -rf ${tmpDir} && mkdir -p ${tmpDir} && npm pack @playwright/mcp@${version} --pack-destination ${tmpDir} 2>/dev/null && tar -xzf ${tmpDir}/playwright-mcp-${version}.tgz -C ${tmpDir} --strip-components=1 && cat ${tmpDir}/package/README.md`,
80
+ { timeout: 30000 },
81
+ (err, stdout) => {
82
+ if (err) { resolve([]); return; }
83
+ const tools = parseMcpReadme(stdout);
84
+ resolve(tools);
85
+ }
86
+ );
87
+ });
88
+ }
89
+
90
+ /**
91
+ * Sync Healer tools table in SKILL.md with latest @playwright/mcp.
92
+ * Returns true if updated, false if already current or failed.
93
+ */
94
+ export async function syncMcpTools(
95
+ skillDest: string,
96
+ verbose = false
97
+ ): Promise<boolean> {
98
+ const latestVersion = await getLatestMcpVersion();
99
+ if (!latestVersion) {
100
+ if (verbose) console.log(chalk.yellow(' âš  Could not fetch latest @playwright/mcp version'));
101
+ return false;
102
+ }
103
+
104
+ if (!existsSync(skillDest)) {
105
+ if (verbose) console.log(chalk.gray(' - SKILL.md not found, skipping MCP sync'));
106
+ return false;
107
+ }
108
+
109
+ const skillContent = readFileSync(skillDest, 'utf-8');
110
+ const storedVersion = getStoredMcpVersion(skillContent);
111
+
112
+ if (storedVersion === latestVersion) {
113
+ if (verbose) console.log(chalk.gray(` - Healer tools current (${latestVersion})`));
114
+ return false;
115
+ }
116
+
117
+ if (verbose) console.log(chalk.blue(` - Updating from ${storedVersion ?? 'unknown'} → ${latestVersion}`));
118
+
119
+ const tools = await fetchMcpTools(latestVersion);
120
+ const toolSet = tools.length > 0 ? tools : DEFAULT_HEALER_TOOLS;
121
+
122
+ const updated = updateHealerTable(skillContent, latestVersion, toolSet);
123
+ writeFileSync(skillDest, updated);
124
+
125
+ if (verbose) {
126
+ if (tools.length > 0) {
127
+ console.log(chalk.green(` ✓ Healer tools synced to ${latestVersion} (${tools.length} tools)`));
128
+ } else {
129
+ console.log(chalk.green(` ✓ Healer tools synced to ${latestVersion} (default set)`));
130
+ }
131
+ }
132
+ return true;
133
+ }
@@ -7,6 +7,7 @@ import {
7
7
  } from 'fs';
8
8
  import { join } from 'path';
9
9
  import chalk from 'chalk';
10
+ import { syncMcpTools } from './mcpSync.js';
10
11
 
11
12
  const SKILL_SRC = new URL('../../.claude/skills/openspec-e2e', import.meta.url).pathname;
12
13
  const CMD_SRC = new URL('../../.claude/commands/opsx', import.meta.url).pathname;
@@ -43,7 +44,6 @@ export async function update(options: UpdateOptions) {
43
44
  if (options.skill !== false) {
44
45
  console.log(chalk.blue('\n─── Updating Skill & Command ───'));
45
46
  try {
46
- // Download npm tarball and extract
47
47
  const tmpDir = '/tmp/openspec-e2e-update';
48
48
  execSync(`rm -rf ${tmpDir} && mkdir -p ${tmpDir}`, { stdio: 'pipe', cwd: projectRoot });
49
49
  execSync(
@@ -54,7 +54,6 @@ export async function update(options: UpdateOptions) {
54
54
  `ls -t ${tmpDir}/openspec-playwright-*.tgz | head -1`,
55
55
  { encoding: 'utf-8', cwd: projectRoot }
56
56
  ).trim();
57
- // Move tarball out before extracting to avoid "overwrite archive" error
58
57
  const tmpTarball = `${tmpDir}/package.tgz`;
59
58
  execSync(`mv "${tarball}" "${tmpTarball}"`, { stdio: 'pipe', cwd: projectRoot });
60
59
  execSync(`tar -xzf "${tmpTarball}" -C ${tmpDir} --strip-components=1`, { stdio: 'pipe', cwd: projectRoot });
@@ -72,6 +71,11 @@ export async function update(options: UpdateOptions) {
72
71
  }
73
72
  }
74
73
 
74
+ // 3. Sync Healer tools with latest @playwright/mcp
75
+ console.log(chalk.blue('\n─── Syncing Healer Tools ───'));
76
+ const skillDest = join(projectRoot, '.claude', 'skills', 'openspec-e2e', 'SKILL.md');
77
+ await syncMcpTools(skillDest, true);
78
+
75
79
  // Summary
76
80
  console.log(chalk.blue('\n─── Summary ───'));
77
81
  console.log(chalk.green(' ✓ Update complete!\n'));
@@ -110,13 +114,11 @@ function installSchemaFrom(schemaSrc: string, projectRoot: string) {
110
114
  const schemaDest = join(projectRoot, 'openspec', 'schemas', 'playwright-e2e');
111
115
 
112
116
  mkdirSync(schemaDest, { recursive: true });
113
- // Copy schema.yaml
114
117
  const schemaYamlSrc = join(schemaSrc, 'schema.yaml');
115
118
  if (existsSync(schemaYamlSrc)) {
116
119
  writeFileSync(join(schemaDest, 'schema.yaml'), readFileSync(schemaYamlSrc));
117
120
  }
118
121
 
119
- // Copy templates
120
122
  const templatesSrc = join(schemaSrc, 'templates');
121
123
  const templatesDest = join(schemaDest, 'templates');
122
124
  if (existsSync(templatesSrc)) {
Binary file