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:*)"
]
}
}
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 withnpm run, anything may follow." It matches arguments too, such asnpm run test -- --watch. Put the*after the subcommand; a rule with a*before it, likeBash(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:*)"]
}
}
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:*)"
]
}
}
Verify it
- Save the setting and restart Claude Code.
- Open
/permissionsand check the allow list. - Say "run the tests." If
npm run testgoes without a prompt, it works. - Say "add lodash." If
npm install lodashprompts, 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, andnpm installis a different prefix so it stays out - When allowing a whole program such as
pnpmornpx, stop the install commands with ask rules — ask is evaluated before allow - For Python, allow
pytest,ruffanduv run, and putpip installin ask
Top comments (1)
Some comments may only be visible to logged-in visitors. Sign in to view all comments.