diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index fef3463..1e0f62c 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -8,7 +8,7 @@ "name": "webmcpify", "source": "./", "description": "WebMCP agent skill for curated core coverage or route-by-route parity — inventory an existing web app, integrate approved tools, then verify and heal them in a real browser.", - "version": "0.6.0" + "version": "0.6.1" } ] } diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json index beb7c53..766dcad 100644 --- a/.claude-plugin/plugin.json +++ b/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "webmcpify", "description": "WebMCP agent skill for curated core coverage or route-by-route parity — inventory an existing web app, integrate approved tools, then verify and heal them in a real browser.", - "version": "0.6.0", + "version": "0.6.1", "author": { "name": "Jonas Tüchler" } diff --git a/.cursor-plugin/plugin.json b/.cursor-plugin/plugin.json index beb7c53..766dcad 100644 --- a/.cursor-plugin/plugin.json +++ b/.cursor-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "webmcpify", "description": "WebMCP agent skill for curated core coverage or route-by-route parity — inventory an existing web app, integrate approved tools, then verify and heal them in a real browser.", - "version": "0.6.0", + "version": "0.6.1", "author": { "name": "Jonas Tüchler" } diff --git a/CHANGELOG.md b/CHANGELOG.md index 4ca0de0..9155e03 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,13 @@ reconstruct them from git history. ## [Unreleased] +## [0.6.1] — 2026-09-19 + +- Pinned the verification harness install to the versions the skill is tested with + (`@playwright/test` matching the Workbench's Playwright) and run its local binary + instead of `npx`, preventing version drift in the direct harness dependencies and + package downloads when the harness runs. + ## [0.6.0] — 2026-09-19 - Tightened eval execution with reviewed versions, bounded runs and approved data; @@ -87,4 +94,5 @@ reconstruct them from git history. [0.5.0]: https://github.com/TueJon/webmcpify/compare/v0.4.0...v0.5.0 [0.5.1]: https://github.com/TueJon/webmcpify/compare/v0.5.0...v0.5.1 [0.6.0]: https://github.com/TueJon/webmcpify/compare/v0.5.1...v0.6.0 -[Unreleased]: https://github.com/TueJon/webmcpify/compare/v0.6.0...HEAD +[0.6.1]: https://github.com/TueJon/webmcpify/compare/v0.6.0...v0.6.1 +[Unreleased]: https://github.com/TueJon/webmcpify/compare/v0.6.1...HEAD diff --git a/gemini-extension.json b/gemini-extension.json index beb7c53..766dcad 100644 --- a/gemini-extension.json +++ b/gemini-extension.json @@ -1,7 +1,7 @@ { "name": "webmcpify", "description": "WebMCP agent skill for curated core coverage or route-by-route parity — inventory an existing web app, integrate approved tools, then verify and heal them in a real browser.", - "version": "0.6.0", + "version": "0.6.1", "author": { "name": "Jonas Tüchler" } diff --git a/package-lock.json b/package-lock.json index eb4d3fe..16c48a3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "webmcpify", - "version": "0.6.0", + "version": "0.6.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "webmcpify", - "version": "0.6.0", + "version": "0.6.1", "license": "MIT", "devDependencies": { "@playwright/test": "^1.54.0", diff --git a/package.json b/package.json index 923ff66..c5f9675 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "description": "WebMCP agent skill for curated core coverage or route-by-route parity — inventory an existing web app, integrate approved tools, then verify and heal them in a real browser.", "type": "module", "license": "MIT", - "version": "0.6.0", + "version": "0.6.1", "publisher": "TueJon", "repository": { "url": "https://github.com/TueJon/webmcpify" diff --git a/release/v0.6.1.md b/release/v0.6.1.md new file mode 100644 index 0000000..14f1fb4 --- /dev/null +++ b/release/v0.6.1.md @@ -0,0 +1,22 @@ +# webmcpify v0.6.1 + +The verification harness now installs exact, tested versions and runs its local +Playwright binary. v0.6.0 removed unpinned package execution from the guidance +step; the harness setup in `references/verify.md` still installed whatever the +registry served as latest. + +## What changed + +- `@playwright/test@1.61.1`, `typescript@5.9.3` and `@types/node@22.20.1` are + installed with `--save-exact`; `@playwright/test` matches the Workbench's + Playwright version. +- The harness runs `./node_modules/.bin/playwright test`, so a missing install + fails instead of downloading a package. +- A repository test fails when the documented harness install is unpinned, uses + `npx`, or diverges from the Workbench's Playwright version. + +## Compatibility + +Backward-compatible patch release. No runtime, template or manifest changes. + +Compare: https://github.com/TueJon/webmcpify/compare/v0.6.0...v0.6.1 diff --git a/skill.json b/skill.json index c1dda65..5a32d81 100644 --- a/skill.json +++ b/skill.json @@ -1,6 +1,6 @@ { "name": "webmcpify", - "version": "0.6.0", + "version": "0.6.1", "description": "WebMCP agent skill for curated core coverage or route-by-route parity — inventory an existing web app, integrate approved tools, then verify and heal them in a real browser.", "license": "MIT", "author": { diff --git a/skills/webmcpify/references/verify.md b/skills/webmcpify/references/verify.md index 734b858..7fb70df 100644 --- a/skills/webmcpify/references/verify.md +++ b/skills/webmcpify/references/verify.md @@ -121,7 +121,7 @@ harness OUTSIDE the repo so the target gains no dependencies: ```sh mkdir -p /tmp/webmcpify-harness && cd /tmp/webmcpify-harness -npm init -y && npm i -D @playwright/test typescript @types/node +npm init -y && npm i -D --save-exact @playwright/test@1.61.1 typescript@5.9.3 @types/node@22.20.1 cat > playwright.config.ts <<'EOF' import { defineConfig } from '@playwright/test'; export default defineConfig({ @@ -132,9 +132,14 @@ EOF WEBMCP_SPEC_DIR=/.webmcpify \ WEBMCP_BASE_URL= \ WEBMCP_PROFILE_DIR= \ -NODE_PATH=/tmp/webmcpify-harness/node_modules npx playwright test +NODE_PATH=/tmp/webmcpify-harness/node_modules ./node_modules/.bin/playwright test ``` +The harness versions are the ones this skill is tested with, and `@playwright/test` +matches the Workbench's Playwright (`scripts/workbench.mjs`). Bump them together, +never to `latest`. The local binary is called directly, so a missing install fails +instead of downloading a package. + `NODE_PATH` lets the out-of-repo spec resolve `@playwright/test`; if the target's tooling ignores `NODE_PATH`, symlink instead: `ln -s /tmp/webmcpify-harness/node_modules /.webmcpify/node_modules` diff --git a/tests/harness-pin.test.mjs b/tests/harness-pin.test.mjs new file mode 100644 index 0000000..706ccfb --- /dev/null +++ b/tests/harness-pin.test.mjs @@ -0,0 +1,23 @@ +import assert from 'node:assert/strict'; +import { readFileSync } from 'node:fs'; +import test from 'node:test'; + +const read = (path) => readFileSync(new URL(`../${path}`, import.meta.url), 'utf8'); + +test('verification harness installs exact top-level versions and uses its local binary', () => { + const verify = read('skills/webmcpify/references/verify.md'); + const installs = verify.split('\n').filter((line) => /\bnpm (i|install)\b/.test(line)); + assert.ok(installs.length > 0, 'verify.md documents the harness install'); + for (const line of installs) { + const packages = line.split(/\s+/).filter((word) => /^@?[a-z0-9./-]+(@[^\s]+)?$/i.test(word) + && /^(@playwright|typescript|@types)/.test(word)); + assert.ok(packages.length > 0, `no harness packages found in: ${line}`); + for (const pkg of packages) assert.match(pkg, /@\d+\.\d+\.\d+$/, `${pkg} is not pinned exactly`); + } + assert.doesNotMatch(verify, /\bnpx (-y )?playwright\b/, 'run the installed binary, not npx'); + + const workbench = read('skills/webmcpify/scripts/workbench.mjs'); + const pinned = workbench.match(/const playwrightVersion = '([^']+)'/)[1]; + assert.match(verify, new RegExp(`@playwright/test@${pinned.replace(/\./g, '\\.')}\\b`), + 'harness @playwright/test must match the Workbench Playwright version'); +});