DEV Community

aicoding-guide
aicoding-guide

Posted on Originally published at aicoding-guide.com

Auto-allow npm scripts in Claude Code without allowing npm install

Originally published at https://aicoding-guide.com.

A confirmation dialog on every npm run lint, npm run test and npm run build is the single biggest drag on working with Claude Code. The scripts in your package.json are commands you wrote yourself, so there is no reason not to allow them as a group.

In short: put Bash(npm run:*) in allow and every npm script stops prompting. npm install is a different prefix, so it is not swept in by accident.

Key point
What you will learn

  • Patterns that allow scripts for npm, pnpm, yarn and npx
  • What :* means, and how to keep install commands out of the rule
  • The equivalent for Python projects (pytest, ruff)

The setting

{
  "permissions": {
    "allow": [
      "Bash(npm run:*)",
      "Bash(npm test)",
      "Bash(npx tsc:*)",
      "Bash(npx vitest:*)",
      "Bash(npx eslint:*)",
      "Bash(npx prettier:*)"
    ],
    "ask": [
      "Bash(npm install:*)",
      "Bash(npm i:*)",
      "Bash(npm uninstall:*)"
    ]
  }
}
Enter fullscreen mode Exit fullscreen mode

npx can run any package, so this allows only the ones you use rather than the whole program. Note that npx is deliberately not in ask: an ask rule prompts even when a more specific allow rule also matches, so Bash(npx:*) in ask would start prompting for the npx tsc you just allowed. Leaving it out means "the ones I allowed run silently, any other npx follows the default behavior" — a prompt in Manual mode.

Glossary
What :* means: Bash(npm run:*) is a prefix match — "starts with npm run, anything may follow." It matches arguments too, such as npm run test -- --watch. Put the * after the subcommand; a rule with a * before it, like Bash(npm * test), triggers a startup warning.

Patterns per package manager

Tool Running scripts Install commands (ask)
npm Bash(npm run:*) Bash(npm install:*), Bash(npm i:*)
pnpm Bash(pnpm run:*), Bash(pnpm test), Bash(pnpm lint) Bash(pnpm add:*), Bash(pnpm install:*)
yarn Bash(yarn run:*), Bash(yarn test) Bash(yarn add:*), Bash(yarn install)
bun Bash(bun run:*) Bash(bun add:*), Bash(bun install:*)

pnpm and yarn let you drop run, as in pnpm lint, so either list the scripts you use individually or allow the whole program and stop the install commands with ask rules. Because ask is evaluated before allow, that combination is safe:

{
  "permissions": {
    "allow": ["Bash(pnpm:*)"],
    "ask": ["Bash(pnpm add:*)", "Bash(pnpm install:*)", "Bash(pnpm remove:*)"]
  }
}
Enter fullscreen mode Exit fullscreen mode

For a Python project

{
  "permissions": {
    "allow": [
      "Bash(pytest:*)",
      "Bash(python -m pytest:*)",
      "Bash(ruff:*)",
      "Bash(mypy:*)",
      "Bash(uv run:*)"
    ],
    "ask": [
      "Bash(pip install:*)",
      "Bash(uv add:*)"
    ]
  }
}
Enter fullscreen mode Exit fullscreen mode

Verify it

  1. Save the setting and restart Claude Code.
  2. Open /permissions and check the allow list.
  3. Say "run the tests." If npm run test goes without a prompt, it works.
  4. Say "add lodash." If npm install lodash prompts, the ask rules work too.

Related settings

Once the scripts run unattended, a hook that always lints after an edit keeps quality up as you widen the automation — see Run lint and format on save with Claude Code hooks. For the overall design, see the parent article, Design permissions in Claude Code's settings.json.

Summary

  • Bash(npm run:*) allows every npm script in one rule, and npm install is a different prefix so it stays out
  • When allowing a whole program such as pnpm or npx, stop the install commands with ask rules — ask is evaluated before allow
  • For Python, allow pytest, ruff and uv run, and put pip install in ask

Top comments (1)

Some comments may only be visible to logged-in visitors. Sign in to view all comments.