From 2e93d2d68e8a08aecbf085156a091cbaf22e1029 Mon Sep 17 00:00:00 2001 From: Devin Rousso Date: Fri, 18 Sep 2026 12:46:24 -0600 Subject: [PATCH] fix(skills): narrow `npm` and `npx` grants the CLI and trace skills preapprove unrelated `npm` and `npx` commands limit automatic approval to Playwright commands --- .../playwright-core/src/tools/skills/playwright-cli/SKILL.md | 4 +++- .../src/tools/skills/playwright-trace/SKILL.md | 2 +- tests/mcp/cli-misc.spec.ts | 4 ++++ tests/mcp/init-agents.spec.ts | 3 +++ 4 files changed, 11 insertions(+), 2 deletions(-) diff --git a/packages/playwright-core/src/tools/skills/playwright-cli/SKILL.md b/packages/playwright-core/src/tools/skills/playwright-cli/SKILL.md index 1c90039039dc0..1551d90a78b05 100644 --- a/packages/playwright-core/src/tools/skills/playwright-cli/SKILL.md +++ b/packages/playwright-core/src/tools/skills/playwright-cli/SKILL.md @@ -1,7 +1,7 @@ --- name: playwright-cli description: Automate browser interactions, test web pages and work with Playwright tests. -allowed-tools: Bash(playwright-cli:*) Bash(npx:*) Bash(npm:*) +allowed-tools: Bash(playwright-cli:*) Bash(npx playwright:*) Bash(npx --no-install playwright:*) --- # Browser Automation with playwright-cli @@ -399,6 +399,8 @@ playwright-cli kill-all ## Installation +Package installation and custom `npm` scripts may require separate approval. + If global `playwright-cli` command is not available, try a local version via `npx playwright cli`: ```bash diff --git a/packages/playwright-core/src/tools/skills/playwright-trace/SKILL.md b/packages/playwright-core/src/tools/skills/playwright-trace/SKILL.md index 126b17a08df46..95d6d47d1efad 100644 --- a/packages/playwright-core/src/tools/skills/playwright-trace/SKILL.md +++ b/packages/playwright-core/src/tools/skills/playwright-trace/SKILL.md @@ -1,7 +1,7 @@ --- name: playwright-trace description: Inspect Playwright trace files from the command line — list actions, view requests, console, errors, snapshots and screenshots. -allowed-tools: Bash(npx:*) +allowed-tools: Bash(npx playwright trace:*) --- # Playwright Trace CLI diff --git a/tests/mcp/cli-misc.spec.ts b/tests/mcp/cli-misc.spec.ts index c99f422704f1f..7d825e8113b55 100644 --- a/tests/mcp/cli-misc.spec.ts +++ b/tests/mcp/cli-misc.spec.ts @@ -63,6 +63,10 @@ test('install workspace w/skills', async ({ cli }, testInfo) => { const skillFile = testInfo.outputPath('.claude', 'skills', 'playwright-cli', 'SKILL.md'); expect(fs.existsSync(skillFile)).toBe(true); + const skillContents = fs.readFileSync(skillFile, 'utf-8'); + expect(skillContents.match(/^allowed-tools: .*/gm)).toEqual([ + 'allowed-tools: Bash(playwright-cli:*) Bash(npx playwright:*) Bash(npx --no-install playwright:*)', + ]); const referencesDir = testInfo.outputPath('.claude', 'skills', 'playwright-cli', 'references'); const references = await fs.promises.readdir(referencesDir); diff --git a/tests/mcp/init-agents.spec.ts b/tests/mcp/init-agents.spec.ts index 08c62fc4d69b2..513b03837139a 100644 --- a/tests/mcp/init-agents.spec.ts +++ b/tests/mcp/init-agents.spec.ts @@ -130,6 +130,9 @@ test('init-skills installs all skills', async ({ }) => { for (const skill of ['playwright-cli', 'playwright-component-testing', 'playwright-trace']) expect(fs.existsSync(path.join(baseDir, '.claude', 'skills', skill, 'SKILL.md'))).toBe(true); expect(fs.existsSync(path.join(baseDir, '.claude', 'skills', 'playwright-cli', 'references', 'tracing.md'))).toBe(true); + + const traceSkill = fs.readFileSync(path.join(baseDir, '.claude', 'skills', 'playwright-trace', 'SKILL.md'), 'utf-8'); + expect(traceSkill.match(/^allowed-tools: .*/gm)).toEqual(['allowed-tools: Bash(npx playwright trace:*)']); }); test('init-skills installs into .agents with --loop agents', async ({ }) => {