openspec-playwright 0.1.30 → 0.1.32
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/.claude/skills/openspec-e2e/SKILL.md +13 -5
- package/dist/commands/doctor.js +2 -1
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/init.js +7 -5
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/mcpSync.js +30 -13
- package/dist/commands/mcpSync.js.map +1 -1
- package/dist/commands/update.js +33 -11
- package/dist/commands/update.js.map +1 -1
- package/openspec-playwright-0.1.32.tgz +0 -0
- package/package.json +3 -2
- package/release-notes.md +2 -2
- package/src/commands/doctor.ts +2 -1
- package/src/commands/init.ts +7 -5
- package/src/commands/mcpSync.ts +31 -13
- package/src/commands/update.ts +40 -16
- package/openspec-playwright-0.1.30.tgz +0 -0
|
@@ -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.
|
|
10
|
+
version: "2.6"
|
|
11
11
|
---
|
|
12
12
|
|
|
13
13
|
## Input
|
|
@@ -207,10 +207,18 @@ If tests fail → analyze failures, use **Playwright MCP tools** to inspect UI s
|
|
|
207
207
|
3. **Attempt heal** (up to 3 times):
|
|
208
208
|
- Apply fix using `browser_snapshot` (prefer `getByRole`, `getByLabel`, `getByText`)
|
|
209
209
|
- Re-run: `openspec-pw run <name> --project=<role>`
|
|
210
|
-
4. **After 3 failed attempts
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
210
|
+
4. **After 3 failed attempts**, collect evidence:
|
|
211
|
+
|
|
212
|
+
**Evidence checklist** (in order, stop at first match):
|
|
213
|
+
| Check | Signal | Decision |
|
|
214
|
+
|-------|--------|----------|
|
|
215
|
+
| `browser_console_messages` | ERROR-level messages present | App bug → `test.skip()` + report "console error" |
|
|
216
|
+
| `browser_snapshot` | Target element missing from DOM | App bug → `test.skip()` + report "element missing" |
|
|
217
|
+
| `browser_snapshot` | Element exists, no errors | Test bug → report recommendation |
|
|
218
|
+
|
|
219
|
+
- **App bug**: `test.skip('app bug — reason: <signal>')` + detailed report entry
|
|
220
|
+
- **Test bug**: report with "likely selector change, verify manually at file:line"
|
|
221
|
+
- Do NOT retry after evidence checklist — evidence is conclusive
|
|
214
222
|
|
|
215
223
|
### 9. Report results
|
|
216
224
|
|
package/dist/commands/doctor.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { existsSync, readFileSync } from 'fs';
|
|
2
2
|
import { join } from 'path';
|
|
3
|
+
import { homedir } from 'os';
|
|
3
4
|
import { execSync } from 'child_process';
|
|
4
5
|
import chalk from 'chalk';
|
|
5
6
|
export async function doctor() {
|
|
@@ -50,7 +51,7 @@ export async function doctor() {
|
|
|
50
51
|
}
|
|
51
52
|
// Playwright MCP (global)
|
|
52
53
|
console.log(chalk.blue('\n─── Playwright MCP ───'));
|
|
53
|
-
const homeDir =
|
|
54
|
+
const homeDir = homedir();
|
|
54
55
|
const claudeJsonPath = join(homeDir, '.claude.json');
|
|
55
56
|
let mcpInstalled = false;
|
|
56
57
|
if (existsSync(claudeJsonPath)) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAC9C,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,CAAC,KAAK,UAAU,MAAM;IAC1B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,sDAAsD,CAAC,CAAC,CAAC;IAEhF,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAClC,IAAI,KAAK,GAAG,IAAI,CAAC;IAEjB,UAAU;IACV,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC;IAC3C,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,QAAQ,CAAC,gBAAgB,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QACtE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,eAAe,IAAI,EAAE,CAAC,CAAC,CAAC;IAClD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC,CAAC;QAChD,KAAK,GAAG,KAAK,CAAC;IAChB,CAAC;IAED,MAAM;IACN,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC;IACzC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,QAAQ,CAAC,eAAe,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QACpE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,WAAW,GAAG,EAAE,CAAC,CAAC,CAAC;IAC7C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC,CAAC;QAC5C,KAAK,GAAG,KAAK,CAAC;IAChB,CAAC;IAED,WAAW;IACX,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC,CAAC;IAC9C,MAAM,WAAW,GAAG,UAAU,CAAC,IAAI,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC,CAAC;IAC9D,IAAI,WAAW,EAAE,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC,CAAC;IACvD,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAC,CAAC;QACvD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC,CAAC;QAClD,KAAK,GAAG,KAAK,CAAC;IAChB,CAAC;IAED,sBAAsB;IACtB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,+BAA+B,CAAC,CAAC,CAAC;IACzD,IAAI,CAAC;QACH,MAAM,EAAE,GAAG,QAAQ,CAAC,0BAA0B,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QAC9E,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,kBAAkB,EAAE,EAAE,CAAC,CAAC,CAAC;IACnD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,uCAAuC,CAAC,CAAC,CAAC;QAChE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,6CAA6C,CAAC,CAAC,CAAC;QACvE,KAAK,GAAG,KAAK,CAAC;IAChB,CAAC;IAED,0BAA0B;IAC1B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC,CAAC;IACpD,MAAM,OAAO,GAAG,OAAO,EAAE,CAAC;IAC1B,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC;IACrD,IAAI,YAAY,GAAG,KAAK,CAAC;IACzB,IAAI,UAAU,CAAC,cAAc,CAAC,EAAE,CAAC;QAC/B,IAAI,CAAC;YACH,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC,CAAC;YACrE,MAAM,SAAS,GAAG,UAAU,EAAE,UAAU,IAAI,EAAE,CAAC;YAC/C,MAAM,QAAQ,GAAG,UAAU,EAAE,QAAQ,EAAE,CAAC,WAAW,CAAC,EAAE,UAAU,IAAI,EAAE,CAAC;YACvE,IAAI,SAAS,CAAC,YAAY,CAAC,IAAI,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;gBACtD,YAAY,GAAG,IAAI,CAAC;YACtB,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,SAAS;QACX,CAAC;IACH,CAAC;IACD,IAAI,YAAY,EAAE,CAAC;QACjB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,uCAAuC,CAAC,CAAC,CAAC;IACpE,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,mCAAmC,CAAC,CAAC,CAAC;QAC5D,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC,CAAC;QACrD,KAAK,GAAG,KAAK,CAAC;IAChB,CAAC;IAED,QAAQ;IACR,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC,CAAC;IACvD,MAAM,QAAQ,GAAG,UAAU,CACzB,IAAI,CAAC,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,cAAc,EAAE,UAAU,CAAC,CACnE,CAAC;IACF,IAAI,QAAQ,EAAE,CAAC;QACb,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,mCAAmC,CAAC,CAAC,CAAC;IAChE,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC,CAAC;QAClD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC,CAAC;QACrD,KAAK,GAAG,KAAK,CAAC;IAChB,CAAC;IAED,YAAY;IACZ,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC,CAAC;IAC/C,MAAM,OAAO,GAAG,UAAU,CACxB,IAAI,CAAC,WAAW,EAAE,OAAO,EAAE,YAAY,EAAE,cAAc,CAAC,CACzD,CAAC;IACF,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC,CAAC;IACrD,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,uCAAuC,CAAC,CAAC,CAAC;QACnE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC,CAAC;IACvD,CAAC;IAED,UAAU;IACV,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC;IAC7C,IAAI,KAAK,EAAE,CAAC;QACV,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAAC,CAAC;QACzD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,iDAAiD,CAAC,CAAC,CAAC;IAC7E,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,sCAAsC,CAAC,CAAC,CAAC;QAC/D,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,kCAAkC,CAAC,CAAC,CAAC;QAC5D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
|
package/dist/commands/init.js
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import { execSync } from 'child_process';
|
|
2
2
|
import { existsSync, readFileSync, writeFileSync, mkdirSync, } from 'fs';
|
|
3
3
|
import { join } from 'path';
|
|
4
|
+
import { homedir } from 'os';
|
|
5
|
+
import { fileURLToPath } from 'url';
|
|
4
6
|
import chalk from 'chalk';
|
|
5
7
|
import { readFile } from 'fs/promises';
|
|
6
8
|
import { syncMcpTools } from './mcpSync.js';
|
|
7
|
-
const TEMPLATE_DIR = new URL('../../templates', import.meta.url)
|
|
8
|
-
const SCHEMA_DIR = new URL('../../schemas', import.meta.url)
|
|
9
|
-
const SKILL_SRC = new URL('../../.claude/skills/openspec-e2e', import.meta.url)
|
|
10
|
-
const CMD_SRC = new URL('../../.claude/commands/opsx/e2e.md', import.meta.url)
|
|
9
|
+
const TEMPLATE_DIR = fileURLToPath(new URL('../../templates', import.meta.url));
|
|
10
|
+
const SCHEMA_DIR = fileURLToPath(new URL('../../schemas', import.meta.url));
|
|
11
|
+
const SKILL_SRC = fileURLToPath(new URL('../../.claude/skills/openspec-e2e', import.meta.url));
|
|
12
|
+
const CMD_SRC = fileURLToPath(new URL('../../.claude/commands/opsx/e2e.md', import.meta.url));
|
|
11
13
|
export async function init(options) {
|
|
12
14
|
console.log(chalk.blue('\n🔧 OpenSpec + Playwright E2E Setup\n'));
|
|
13
15
|
const projectRoot = process.cwd();
|
|
@@ -36,7 +38,7 @@ export async function init(options) {
|
|
|
36
38
|
if (options.mcp !== false) {
|
|
37
39
|
console.log(chalk.blue('\n─── Installing Playwright MCP ───'));
|
|
38
40
|
// Check if playwright MCP already exists in global config
|
|
39
|
-
const claudeJsonPath = join(
|
|
41
|
+
const claudeJsonPath = join(homedir(), '.claude.json');
|
|
40
42
|
const claudeJson = existsSync(claudeJsonPath) ? JSON.parse(readFileSync(claudeJsonPath, 'utf-8')) : {};
|
|
41
43
|
const globalMcp = claudeJson?.mcpServers ?? {};
|
|
42
44
|
const localMcp = claudeJson?.projects?.[projectRoot]?.mcpServers ?? {};
|
|
@@ -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,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;AAC1B,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,iBAAiB,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.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,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,MAAM,YAAY,GAAG,aAAa,CAAC,IAAI,GAAG,CAAC,iBAAiB,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAChF,MAAM,UAAU,GAAG,aAAa,CAAC,IAAI,GAAG,CAAC,eAAe,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC5E,MAAM,SAAS,GAAG,aAAa,CAAC,IAAI,GAAG,CAAC,mCAAmC,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC/F,MAAM,OAAO,GAAG,aAAa,CAAC,IAAI,GAAG,CAAC,oCAAoC,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAQ9F,MAAM,CAAC,KAAK,UAAU,IAAI,CAAC,OAAoB;IAC7C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,wCAAwC,CAAC,CAAC,CAAC;IAElE,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAElC,yBAAyB;IACzB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC,CAAC;IAEjD,MAAM,OAAO,GAAG,OAAO,CAAC,gBAAgB,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;IAC3D,MAAM,MAAM,GAAG,OAAO,CAAC,eAAe,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;IACrD,MAAM,WAAW,GAAG,OAAO,CAAC,wDAAwD,EAAE,UAAU,EAAE,IAAI,CAAC,CAAC;IAExG,IAAI,CAAC,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC;QACxB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,6BAA6B,CAAC,CAAC,CAAC;QACtD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,2BAA2B,CAAC,CAAC,CAAC;IAEtD,oBAAoB;IACpB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC;QAC/C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,yDAAyD,CAAC,CAAC,CAAC;QACrF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,uCAAuC,CAAC,CAAC,CAAC;QACjE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC;QAC3C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC,CAAC;QAC1D,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC,CAAC;QAC/C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,sCAAsC,CAAC,CAAC,CAAC;QAChE,OAAO;IACT,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC,CAAC;IAErD,qCAAqC;IACrC,IAAI,OAAO,CAAC,GAAG,KAAK,KAAK,EAAE,CAAC;QAC1B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,qCAAqC,CAAC,CAAC,CAAC;QAE/D,0DAA0D;QAC1D,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,cAAc,CAAC,CAAC;QACvD,MAAM,UAAU,GAAG,UAAU,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACvG,MAAM,SAAS,GAAG,UAAU,EAAE,UAAU,IAAI,EAAE,CAAC;QAC/C,MAAM,QAAQ,GAAG,UAAU,EAAE,QAAQ,EAAE,CAAC,WAAW,CAAC,EAAE,UAAU,IAAI,EAAE,CAAC;QAEvE,IAAI,SAAS,CAAC,YAAY,CAAC,IAAI,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;YACtD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,sCAAsC,CAAC,CAAC,CAAC;QACnE,CAAC;aAAM,CAAC;YACN,IAAI,CAAC;gBACH,QAAQ,CAAC,sDAAsD,EAAE;oBAC/D,GAAG,EAAE,WAAW;oBAChB,KAAK,EAAE,SAAS;iBACjB,CAAC,CAAC;gBACH,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,uCAAuC,CAAC,CAAC,CAAC;gBAClE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,qCAAqC,CAAC,CAAC,CAAC;YACjE,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,kCAAkC,CAAC,CAAC,CAAC;gBAC9D,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,sEAAsE,CAAC,CAAC,CAAC;gBAChG,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,oDAAoD,CAAC,CAAC,CAAC;YAChF,CAAC;QACH,CAAC;IACH,CAAC;IAED,sBAAsB;IACtB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,wCAAwC,CAAC,CAAC,CAAC;IAClE,MAAM,YAAY,CAAC,WAAW,CAAC,CAAC;IAEhC,mDAAmD;IACnD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC,CAAC;IAC1D,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,cAAc,EAAE,UAAU,CAAC,CAAC;IACrF,MAAM,YAAY,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IAEpC,6BAA6B;IAC7B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,sCAAsC,CAAC,CAAC,CAAC;IAChE,MAAM,aAAa,CAAC,WAAW,CAAC,CAAC;IAEjC,wBAAwB;IACxB,IAAI,OAAO,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;QAC3B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC,CAAC;QAC1D,MAAM,gBAAgB,CAAC,WAAW,CAAC,CAAC;IACtC,CAAC;IAED,aAAa;IACb,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC;IAC7C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAC,CAAC;IAElD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC;IACvC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,sEAAsE,CAAC,CAAC,CAAC;IAChG,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,sEAAsE,CAAC,CAAC,CAAC;IAChG,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,gEAAgE,CAAC,CAAC,CAAC;IAC1F,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,0DAA0D,CAAC,CAAC,CAAC;IACpF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,mDAAmD,CAAC,CAAC,CAAC;IAC7E,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,+CAA+C,CAAC,CAAC,CAAC;IAEzE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC;IACzC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,2DAA2D,CAAC,CAAC,CAAC;IACrF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,6CAA6C,CAAC,CAAC,CAAC;IACvE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,kCAAkC,CAAC,CAAC,CAAC;AAC9D,CAAC;AAED,KAAK,UAAU,YAAY,CAAC,WAAmB;IAC7C,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;IACzD,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;IACjD,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;IAExD,aAAa;IACb,SAAS,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACzC,MAAM,YAAY,GAAG,MAAM,QAAQ,CAAC,SAAS,GAAG,WAAW,EAAE,OAAO,CAAC,CAAC;IACtE,aAAa,CAAC,IAAI,CAAC,QAAQ,EAAE,UAAU,CAAC,EAAE,YAAY,CAAC,CAAC;IACxD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,oCAAoC,CAAC,CAAC,CAAC;IAE/D,eAAe;IACf,SAAS,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACrD,MAAM,UAAU,GAAG,MAAM,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IACpD,aAAa,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,UAAU,CAAC,CAAC;IAC1D,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,kCAAkC,CAAC,CAAC,CAAC;AAC/D,CAAC;AAED,KAAK,UAAU,gBAAgB,CAAC,WAAmB;IACjD,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC;IAC1D,SAAS,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAEzC,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;IAChD,IAAI,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QACzB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,2CAA2C,CAAC,CAAC,CAAC;IACvE,CAAC;SAAM,CAAC;QACN,MAAM,WAAW,GAAG,MAAM,QAAQ,CAAC,YAAY,GAAG,eAAe,EAAE,OAAO,CAAC,CAAC;QAC5E,aAAa,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;QACrC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,8CAA8C,CAAC,CAAC,CAAC;IAC3E,CAAC;IAED,yBAAyB;IACzB,MAAM,aAAa,GAAG,IAAI,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC;IACtD,IAAI,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;QAC9B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,4CAA4C,CAAC,CAAC,CAAC;IACxE,CAAC;SAAM,CAAC;QACN,MAAM,WAAW,GAAG,MAAM,QAAQ,CAAC,YAAY,GAAG,gBAAgB,EAAE,OAAO,CAAC,CAAC;QAC7E,aAAa,CAAC,aAAa,EAAE,WAAW,CAAC,CAAC;QAC1C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,+CAA+C,CAAC,CAAC,CAAC;IAC5E,CAAC;IAED,4BAA4B;IAC5B,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,EAAE,kBAAkB,CAAC,CAAC;IACrD,IAAI,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC1B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,+CAA+C,CAAC,CAAC,CAAC;IAC3E,CAAC;SAAM,CAAC;QACN,MAAM,YAAY,GAAG,MAAM,QAAQ,CAAC,YAAY,GAAG,mBAAmB,EAAE,OAAO,CAAC,CAAC;QACjF,aAAa,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;QACvC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,kDAAkD,CAAC,CAAC,CAAC;IAC/E,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,qDAAqD,CAAC,CAAC,CAAC;AACjF,CAAC;AAED,KAAK,UAAU,aAAa,CAAC,WAAmB;IAC9C,MAAM,SAAS,GAAG,UAAU,GAAG,iBAAiB,CAAC;IACjD,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,EAAE,UAAU,EAAE,SAAS,EAAE,gBAAgB,CAAC,CAAC;IAC9E,MAAM,WAAW,GAAG,CAAC,aAAa,CAAC,CAAC;IAEpC,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3C,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;QAC/B,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;QAClC,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;QACpC,IAAI,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACpB,aAAa,CAAC,IAAI,EAAE,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC;QACzC,CAAC;IACH,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,SAAS,CAAC,aAAa,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9C,MAAM,aAAa,GAAG,CAAC,cAAc,EAAE,WAAW,EAAE,aAAa,EAAE,sBAAsB,CAAC,CAAC;IAC3F,KAAK,MAAM,IAAI,IAAI,aAAa,EAAE,CAAC;QACjC,MAAM,GAAG,GAAG,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;QACrC,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;QACvC,IAAI,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACpB,aAAa,CAAC,IAAI,EAAE,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC;QACzC,CAAC;IACH,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,wDAAwD,CAAC,CAAC,CAAC;AACrF,CAAC;AAED,SAAS,OAAO,CACd,GAAW,EACX,IAAY,EACZ,MAAM,GAAG,KAAK;IAEd,IAAI,CAAC;QACH,QAAQ,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;QACjC,IAAI,CAAC,MAAM;YAAE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,IAAI,QAAQ,CAAC,CAAC,CAAC;QAC3D,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,IAAI,CAAC,MAAM;YAAE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,IAAI,YAAY,CAAC,CAAC,CAAC;QAChE,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
|
package/dist/commands/mcpSync.js
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { exec } from 'child_process';
|
|
2
|
-
import { existsSync, readFileSync, writeFileSync } from 'fs';
|
|
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';
|
|
3
6
|
import chalk from 'chalk';
|
|
7
|
+
import * as tar from 'tar';
|
|
4
8
|
export const MCP_VERSION_MARKER = '<!-- MCP_VERSION:';
|
|
5
9
|
export const DEFAULT_HEALER_TOOLS = [
|
|
6
10
|
{ name: 'browser_navigate', purpose: "Go to the failing test's page" },
|
|
@@ -51,6 +55,13 @@ export function getLatestMcpVersion() {
|
|
|
51
55
|
});
|
|
52
56
|
});
|
|
53
57
|
}
|
|
58
|
+
const execAsync = promisify(exec);
|
|
59
|
+
/** Extract a .tgz tarball to a destination directory (cross-platform) */
|
|
60
|
+
async function extractTarball(tarballPath, destDir) {
|
|
61
|
+
rmSync(destDir, { recursive: true, force: true });
|
|
62
|
+
mkdirSync(destDir, { recursive: true });
|
|
63
|
+
await tar.extract({ file: tarballPath, cwd: destDir, strip: 1 });
|
|
64
|
+
}
|
|
54
65
|
/** Parse README markdown to extract browser_* tool entries */
|
|
55
66
|
function parseMcpReadme(content) {
|
|
56
67
|
const tools = [];
|
|
@@ -69,18 +80,24 @@ function parseMcpReadme(content) {
|
|
|
69
80
|
* Fetch @playwright/mcp tools from npm package.
|
|
70
81
|
* Downloads the tarball, extracts README, parses tool names.
|
|
71
82
|
*/
|
|
72
|
-
export function fetchMcpTools(version) {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
83
|
+
export async function fetchMcpTools(version) {
|
|
84
|
+
const tmpDir = join(tmpdir(), `openspec-pw-mcp-${version}`);
|
|
85
|
+
try {
|
|
86
|
+
await execAsync(`npm pack @playwright/mcp@${version} --pack-destination ${tmpDir}`, { timeout: 30000 });
|
|
87
|
+
const tgzFiles = readdirSync(tmpDir).filter(f => f.startsWith('playwright-mcp-') && f.endsWith('.tgz'));
|
|
88
|
+
if (tgzFiles.length === 0)
|
|
89
|
+
return [];
|
|
90
|
+
const tarballPath = join(tmpDir, tgzFiles[0]);
|
|
91
|
+
const extractDir = join(tmpDir, 'pkg');
|
|
92
|
+
await extractTarball(tarballPath, extractDir);
|
|
93
|
+
const readmePath = join(extractDir, 'README.md');
|
|
94
|
+
const content = existsSync(readmePath) ? readFileSync(readmePath, 'utf-8') : '';
|
|
95
|
+
rmSync(tmpDir, { recursive: true, force: true });
|
|
96
|
+
return parseMcpReadme(content);
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
return [];
|
|
100
|
+
}
|
|
84
101
|
}
|
|
85
102
|
/**
|
|
86
103
|
* Sync Healer tools table in SKILL.md with latest @playwright/mcp.
|
|
@@ -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,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"mcpSync.js","sourceRoot":"","sources":["../../src/commands/mcpSync.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/update.js
CHANGED
|
@@ -1,14 +1,27 @@
|
|
|
1
1
|
import { execSync } from 'child_process';
|
|
2
|
-
import { existsSync, readFileSync, writeFileSync, mkdirSync, } from 'fs';
|
|
2
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync, rmSync, readdirSync, statSync, } from 'fs';
|
|
3
3
|
import { join } from 'path';
|
|
4
|
+
import { tmpdir } from 'os';
|
|
5
|
+
import { promisify } from 'util';
|
|
6
|
+
import { fileURLToPath } from 'url';
|
|
7
|
+
import { exec } from 'child_process';
|
|
4
8
|
import chalk from 'chalk';
|
|
9
|
+
import * as tar from 'tar';
|
|
5
10
|
import { syncMcpTools } from './mcpSync.js';
|
|
6
|
-
const SKILL_SRC = new URL('../../.claude/skills/openspec-e2e', import.meta.url)
|
|
7
|
-
const CMD_SRC = new URL('../../.claude/commands/opsx', import.meta.url)
|
|
8
|
-
const SCHEMA_DIR = new URL('../../schemas', import.meta.url)
|
|
11
|
+
const SKILL_SRC = fileURLToPath(new URL('../../.claude/skills/openspec-e2e', import.meta.url));
|
|
12
|
+
const CMD_SRC = fileURLToPath(new URL('../../.claude/commands/opsx', import.meta.url));
|
|
13
|
+
const SCHEMA_DIR = fileURLToPath(new URL('../../schemas', import.meta.url));
|
|
9
14
|
export async function update(options) {
|
|
10
15
|
console.log(chalk.blue('\n🔄 Updating OpenSpec + Playwright E2E\n'));
|
|
11
16
|
const projectRoot = process.cwd();
|
|
17
|
+
// Check if init has been run
|
|
18
|
+
const hasSkill = existsSync(join(projectRoot, '.claude', 'skills', 'openspec-e2e', 'SKILL.md'));
|
|
19
|
+
const hasOpenSpec = existsSync(join(projectRoot, 'openspec'));
|
|
20
|
+
if (!hasSkill && !hasOpenSpec) {
|
|
21
|
+
console.log(chalk.yellow(' ⚠ OpenSpec + Playwright E2E not initialized.'));
|
|
22
|
+
console.log(chalk.gray(' Run "openspec-pw init" first to set up the integration.\n'));
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
12
25
|
// 1. Update CLI tool from npm
|
|
13
26
|
if (options.cli !== false) {
|
|
14
27
|
console.log(chalk.blue('─── Updating CLI ───'));
|
|
@@ -25,17 +38,26 @@ export async function update(options) {
|
|
|
25
38
|
if (options.skill !== false) {
|
|
26
39
|
console.log(chalk.blue('\n─── Updating Skill & Command ───'));
|
|
27
40
|
try {
|
|
28
|
-
const tmpDir = '
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
41
|
+
const tmpDir = join(tmpdir(), 'openspec-e2e-update');
|
|
42
|
+
rmSync(tmpDir, { recursive: true, force: true });
|
|
43
|
+
mkdirSync(tmpDir, { recursive: true });
|
|
44
|
+
const execAsync = promisify(exec);
|
|
45
|
+
await execAsync(`npm pack openspec-playwright --pack-destination ${tmpDir}`, { timeout: 30000 });
|
|
46
|
+
// Find the latest tarball by mtime
|
|
47
|
+
const tgzFiles = readdirSync(tmpDir)
|
|
48
|
+
.filter(f => f.startsWith('openspec-playwright-') && f.endsWith('.tgz'))
|
|
49
|
+
.map(f => ({ name: f, mtime: statSync(join(tmpDir, f)).mtimeMs }))
|
|
50
|
+
.sort((a, b) => b.mtime - a.mtime);
|
|
51
|
+
if (tgzFiles.length === 0)
|
|
52
|
+
throw new Error('No tarball found');
|
|
53
|
+
const tarballPath = join(tmpDir, tgzFiles[0].name);
|
|
54
|
+
// Extract tarball
|
|
55
|
+
await tar.extract({ file: tarballPath, cwd: tmpDir, strip: 1 });
|
|
35
56
|
const skillSrc = join(tmpDir, '.claude', 'skills', 'openspec-e2e', 'SKILL.md');
|
|
36
57
|
const cmdSrc = join(tmpDir, '.claude', 'commands', 'opsx', 'e2e.md');
|
|
37
58
|
const schemaSrc = join(tmpDir, 'schemas', 'playwright-e2e');
|
|
38
59
|
installSkillFrom(skillSrc, cmdSrc, schemaSrc, projectRoot);
|
|
60
|
+
rmSync(tmpDir, { recursive: true, force: true });
|
|
39
61
|
console.log(chalk.green(' ✓ Skill & command updated to latest'));
|
|
40
62
|
}
|
|
41
63
|
catch {
|
|
@@ -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,
|
|
1
|
+
{"version":3,"file":"update.js","sourceRoot":"","sources":["../../src/commands/update.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,UAAU,EACjB,YAAY,EACZ,aAAa,EACb,SAAS,EACT,MAAM,EACN,WAAW,EACX,QAAQ,GACT,MAAM,IAAI,CAAC;AACZ,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,MAAM,EAAE,MAAM,IAAI,CAAC;AAC5B,OAAO,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AACrC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,KAAK,GAAG,MAAM,KAAK,CAAC;AAC3B,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,MAAM,SAAS,GAAG,aAAa,CAAC,IAAI,GAAG,CAAC,mCAAmC,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC/F,MAAM,OAAO,GAAG,aAAa,CAAC,IAAI,GAAG,CAAC,6BAA6B,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AACvF,MAAM,UAAU,GAAG,aAAa,CAAC,IAAI,GAAG,CAAC,eAAe,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAO5E,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,6BAA6B;IAC7B,MAAM,QAAQ,GAAG,UAAU,CAAC,IAAI,CAAC,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,cAAc,EAAE,UAAU,CAAC,CAAC,CAAC;IAChG,MAAM,WAAW,GAAG,UAAU,CAAC,IAAI,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC,CAAC;IAC9D,IAAI,CAAC,QAAQ,IAAI,CAAC,WAAW,EAAE,CAAC;QAC9B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,gDAAgD,CAAC,CAAC,CAAC;QAC5E,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,6DAA6D,CAAC,CAAC,CAAC;QACvF,OAAO;IACT,CAAC;IAED,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,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,EAAE,qBAAqB,CAAC,CAAC;YACrD,MAAM,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;YACjD,SAAS,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAEvC,MAAM,SAAS,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;YAClC,MAAM,SAAS,CACb,mDAAmD,MAAM,EAAE,EAC3D,EAAE,OAAO,EAAE,KAAK,EAAE,CACnB,CAAC;YAEF,mCAAmC;YACnC,MAAM,QAAQ,GAAG,WAAW,CAAC,MAAM,CAAC;iBACjC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,sBAAsB,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;iBACvE,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;iBACjE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;YACrC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;gBAAE,MAAM,IAAI,KAAK,CAAC,kBAAkB,CAAC,CAAC;YAC/D,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YAEnD,kBAAkB;YAClB,MAAM,GAAG,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;YAEhE,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,MAAM,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;YACjD,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,mDAAmD;IACnD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC,CAAC;IAC1D,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,cAAc,EAAE,UAAU,CAAC,CAAC;IACrF,MAAM,YAAY,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IAEpC,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,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,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"}
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "openspec-playwright",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.32",
|
|
4
4
|
"description": "OpenSpec + Playwright E2E verification setup tool for Claude Code",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -13,7 +13,8 @@
|
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
15
|
"chalk": "^5.3.0",
|
|
16
|
-
"commander": "^12.1.0"
|
|
16
|
+
"commander": "^12.1.0",
|
|
17
|
+
"tar": "^7.0.0"
|
|
17
18
|
},
|
|
18
19
|
"devDependencies": {
|
|
19
20
|
"@types/node": "^22.0.0",
|
package/release-notes.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
## What's Changed
|
|
2
2
|
|
|
3
|
-
-
|
|
3
|
+
- fix: cross-platform support for Windows/Linux/macOS
|
|
4
4
|
|
|
5
|
-
**Full Changelog**: https://github.com/wxhou/openspec-playwright/releases/tag/v0.1.
|
|
5
|
+
**Full Changelog**: https://github.com/wxhou/openspec-playwright/releases/tag/v0.1.32
|
package/src/commands/doctor.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { existsSync, readFileSync } from 'fs';
|
|
2
2
|
import { join } from 'path';
|
|
3
|
+
import { homedir } from 'os';
|
|
3
4
|
import { execSync } from 'child_process';
|
|
4
5
|
import chalk from 'chalk';
|
|
5
6
|
|
|
@@ -53,7 +54,7 @@ export async function doctor() {
|
|
|
53
54
|
|
|
54
55
|
// Playwright MCP (global)
|
|
55
56
|
console.log(chalk.blue('\n─── Playwright MCP ───'));
|
|
56
|
-
const homeDir =
|
|
57
|
+
const homeDir = homedir();
|
|
57
58
|
const claudeJsonPath = join(homeDir, '.claude.json');
|
|
58
59
|
let mcpInstalled = false;
|
|
59
60
|
if (existsSync(claudeJsonPath)) {
|
package/src/commands/init.ts
CHANGED
|
@@ -6,14 +6,16 @@ import {
|
|
|
6
6
|
mkdirSync,
|
|
7
7
|
} from 'fs';
|
|
8
8
|
import { join } from 'path';
|
|
9
|
+
import { homedir } from 'os';
|
|
10
|
+
import { fileURLToPath } from 'url';
|
|
9
11
|
import chalk from 'chalk';
|
|
10
12
|
import { readFile } from 'fs/promises';
|
|
11
13
|
import { syncMcpTools } from './mcpSync.js';
|
|
12
14
|
|
|
13
|
-
const TEMPLATE_DIR = new URL('../../templates', import.meta.url)
|
|
14
|
-
const SCHEMA_DIR = new URL('../../schemas', import.meta.url)
|
|
15
|
-
const SKILL_SRC = new URL('../../.claude/skills/openspec-e2e', import.meta.url)
|
|
16
|
-
const CMD_SRC = new URL('../../.claude/commands/opsx/e2e.md', import.meta.url)
|
|
15
|
+
const TEMPLATE_DIR = fileURLToPath(new URL('../../templates', import.meta.url));
|
|
16
|
+
const SCHEMA_DIR = fileURLToPath(new URL('../../schemas', import.meta.url));
|
|
17
|
+
const SKILL_SRC = fileURLToPath(new URL('../../.claude/skills/openspec-e2e', import.meta.url));
|
|
18
|
+
const CMD_SRC = fileURLToPath(new URL('../../.claude/commands/opsx/e2e.md', import.meta.url));
|
|
17
19
|
|
|
18
20
|
export interface InitOptions {
|
|
19
21
|
change?: string;
|
|
@@ -56,7 +58,7 @@ export async function init(options: InitOptions) {
|
|
|
56
58
|
console.log(chalk.blue('\n─── Installing Playwright MCP ───'));
|
|
57
59
|
|
|
58
60
|
// Check if playwright MCP already exists in global config
|
|
59
|
-
const claudeJsonPath = join(
|
|
61
|
+
const claudeJsonPath = join(homedir(), '.claude.json');
|
|
60
62
|
const claudeJson = existsSync(claudeJsonPath) ? JSON.parse(readFileSync(claudeJsonPath, 'utf-8')) : {};
|
|
61
63
|
const globalMcp = claudeJson?.mcpServers ?? {};
|
|
62
64
|
const localMcp = claudeJson?.projects?.[projectRoot]?.mcpServers ?? {};
|
package/src/commands/mcpSync.ts
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { exec } from 'child_process';
|
|
2
|
-
import { existsSync, readFileSync, writeFileSync } from 'fs';
|
|
2
|
+
import { existsSync, readdirSync, readFileSync, writeFileSync, mkdirSync, rmSync } from 'fs';
|
|
3
3
|
import { join } from 'path';
|
|
4
|
+
import { tmpdir } from 'os';
|
|
5
|
+
import { promisify } from 'util';
|
|
4
6
|
import chalk from 'chalk';
|
|
7
|
+
import * as tar from 'tar';
|
|
5
8
|
|
|
6
9
|
export const MCP_VERSION_MARKER = '<!-- MCP_VERSION:';
|
|
7
10
|
|
|
@@ -53,6 +56,15 @@ export function getLatestMcpVersion(): Promise<string | null> {
|
|
|
53
56
|
});
|
|
54
57
|
}
|
|
55
58
|
|
|
59
|
+
const execAsync = promisify(exec);
|
|
60
|
+
|
|
61
|
+
/** Extract a .tgz tarball to a destination directory (cross-platform) */
|
|
62
|
+
async function extractTarball(tarballPath: string, destDir: string): Promise<void> {
|
|
63
|
+
rmSync(destDir, { recursive: true, force: true });
|
|
64
|
+
mkdirSync(destDir, { recursive: true });
|
|
65
|
+
await tar.extract({ file: tarballPath, cwd: destDir, strip: 1 });
|
|
66
|
+
}
|
|
67
|
+
|
|
56
68
|
/** Parse README markdown to extract browser_* tool entries */
|
|
57
69
|
function parseMcpReadme(content: string): Array<{ name: string; purpose: string }> {
|
|
58
70
|
const tools: Array<{ name: string; purpose: string }> = [];
|
|
@@ -72,19 +84,25 @@ function parseMcpReadme(content: string): Array<{ name: string; purpose: string
|
|
|
72
84
|
* Fetch @playwright/mcp tools from npm package.
|
|
73
85
|
* Downloads the tarball, extracts README, parses tool names.
|
|
74
86
|
*/
|
|
75
|
-
export function fetchMcpTools(version: string): Promise<Array<{ name: string; purpose: string }>> {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
`
|
|
80
|
-
{ timeout: 30000 }
|
|
81
|
-
(err, stdout) => {
|
|
82
|
-
if (err) { resolve([]); return; }
|
|
83
|
-
const tools = parseMcpReadme(stdout);
|
|
84
|
-
resolve(tools);
|
|
85
|
-
}
|
|
87
|
+
export async function fetchMcpTools(version: string): Promise<Array<{ name: string; purpose: string }>> {
|
|
88
|
+
const tmpDir = join(tmpdir(), `openspec-pw-mcp-${version}`);
|
|
89
|
+
try {
|
|
90
|
+
await execAsync(
|
|
91
|
+
`npm pack @playwright/mcp@${version} --pack-destination ${tmpDir}`,
|
|
92
|
+
{ timeout: 30000 }
|
|
86
93
|
);
|
|
87
|
-
|
|
94
|
+
const tgzFiles = readdirSync(tmpDir).filter(f => f.startsWith('playwright-mcp-') && f.endsWith('.tgz'));
|
|
95
|
+
if (tgzFiles.length === 0) return [];
|
|
96
|
+
const tarballPath = join(tmpDir, tgzFiles[0]);
|
|
97
|
+
const extractDir = join(tmpDir, 'pkg');
|
|
98
|
+
await extractTarball(tarballPath, extractDir);
|
|
99
|
+
const readmePath = join(extractDir, 'README.md');
|
|
100
|
+
const content = existsSync(readmePath) ? readFileSync(readmePath, 'utf-8') : '';
|
|
101
|
+
rmSync(tmpDir, { recursive: true, force: true });
|
|
102
|
+
return parseMcpReadme(content);
|
|
103
|
+
} catch {
|
|
104
|
+
return [];
|
|
105
|
+
}
|
|
88
106
|
}
|
|
89
107
|
|
|
90
108
|
/**
|
package/src/commands/update.ts
CHANGED
|
@@ -1,17 +1,24 @@
|
|
|
1
1
|
import { execSync } from 'child_process';
|
|
2
|
-
import {
|
|
3
|
-
existsSync,
|
|
2
|
+
import { existsSync,
|
|
4
3
|
readFileSync,
|
|
5
4
|
writeFileSync,
|
|
6
5
|
mkdirSync,
|
|
6
|
+
rmSync,
|
|
7
|
+
readdirSync,
|
|
8
|
+
statSync,
|
|
7
9
|
} from 'fs';
|
|
8
10
|
import { join } from 'path';
|
|
11
|
+
import { tmpdir } from 'os';
|
|
12
|
+
import { promisify } from 'util';
|
|
13
|
+
import { fileURLToPath } from 'url';
|
|
14
|
+
import { exec } from 'child_process';
|
|
9
15
|
import chalk from 'chalk';
|
|
16
|
+
import * as tar from 'tar';
|
|
10
17
|
import { syncMcpTools } from './mcpSync.js';
|
|
11
18
|
|
|
12
|
-
const SKILL_SRC = new URL('../../.claude/skills/openspec-e2e', import.meta.url)
|
|
13
|
-
const CMD_SRC = new URL('../../.claude/commands/opsx', import.meta.url)
|
|
14
|
-
const SCHEMA_DIR = new URL('../../schemas', import.meta.url)
|
|
19
|
+
const SKILL_SRC = fileURLToPath(new URL('../../.claude/skills/openspec-e2e', import.meta.url));
|
|
20
|
+
const CMD_SRC = fileURLToPath(new URL('../../.claude/commands/opsx', import.meta.url));
|
|
21
|
+
const SCHEMA_DIR = fileURLToPath(new URL('../../schemas', import.meta.url));
|
|
15
22
|
|
|
16
23
|
export interface UpdateOptions {
|
|
17
24
|
cli?: boolean;
|
|
@@ -23,6 +30,15 @@ export async function update(options: UpdateOptions) {
|
|
|
23
30
|
|
|
24
31
|
const projectRoot = process.cwd();
|
|
25
32
|
|
|
33
|
+
// Check if init has been run
|
|
34
|
+
const hasSkill = existsSync(join(projectRoot, '.claude', 'skills', 'openspec-e2e', 'SKILL.md'));
|
|
35
|
+
const hasOpenSpec = existsSync(join(projectRoot, 'openspec'));
|
|
36
|
+
if (!hasSkill && !hasOpenSpec) {
|
|
37
|
+
console.log(chalk.yellow(' ⚠ OpenSpec + Playwright E2E not initialized.'));
|
|
38
|
+
console.log(chalk.gray(' Run "openspec-pw init" first to set up the integration.\n'));
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
|
|
26
42
|
// 1. Update CLI tool from npm
|
|
27
43
|
if (options.cli !== false) {
|
|
28
44
|
console.log(chalk.blue('─── Updating CLI ───'));
|
|
@@ -44,25 +60,33 @@ export async function update(options: UpdateOptions) {
|
|
|
44
60
|
if (options.skill !== false) {
|
|
45
61
|
console.log(chalk.blue('\n─── Updating Skill & Command ───'));
|
|
46
62
|
try {
|
|
47
|
-
const tmpDir = '
|
|
48
|
-
|
|
49
|
-
|
|
63
|
+
const tmpDir = join(tmpdir(), 'openspec-e2e-update');
|
|
64
|
+
rmSync(tmpDir, { recursive: true, force: true });
|
|
65
|
+
mkdirSync(tmpDir, { recursive: true });
|
|
66
|
+
|
|
67
|
+
const execAsync = promisify(exec);
|
|
68
|
+
await execAsync(
|
|
50
69
|
`npm pack openspec-playwright --pack-destination ${tmpDir}`,
|
|
51
|
-
{
|
|
70
|
+
{ timeout: 30000 }
|
|
52
71
|
);
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
72
|
+
|
|
73
|
+
// Find the latest tarball by mtime
|
|
74
|
+
const tgzFiles = readdirSync(tmpDir)
|
|
75
|
+
.filter(f => f.startsWith('openspec-playwright-') && f.endsWith('.tgz'))
|
|
76
|
+
.map(f => ({ name: f, mtime: statSync(join(tmpDir, f)).mtimeMs }))
|
|
77
|
+
.sort((a, b) => b.mtime - a.mtime);
|
|
78
|
+
if (tgzFiles.length === 0) throw new Error('No tarball found');
|
|
79
|
+
const tarballPath = join(tmpDir, tgzFiles[0].name);
|
|
80
|
+
|
|
81
|
+
// Extract tarball
|
|
82
|
+
await tar.extract({ file: tarballPath, cwd: tmpDir, strip: 1 });
|
|
60
83
|
|
|
61
84
|
const skillSrc = join(tmpDir, '.claude', 'skills', 'openspec-e2e', 'SKILL.md');
|
|
62
85
|
const cmdSrc = join(tmpDir, '.claude', 'commands', 'opsx', 'e2e.md');
|
|
63
86
|
const schemaSrc = join(tmpDir, 'schemas', 'playwright-e2e');
|
|
64
87
|
|
|
65
88
|
installSkillFrom(skillSrc, cmdSrc, schemaSrc, projectRoot);
|
|
89
|
+
rmSync(tmpDir, { recursive: true, force: true });
|
|
66
90
|
console.log(chalk.green(' ✓ Skill & command updated to latest'));
|
|
67
91
|
} catch {
|
|
68
92
|
console.log(chalk.yellow(' ⚠ Failed to update skill/command from npm'));
|
|
Binary file
|