Course · Claude Code · Permissions & modes
Pre-approve safe commands and run shell inline
Some prompts arrive so often that answering them stops being a safety check and becomes a reflex. Continue the rename from the preceding permission pages, where processPayment in the course’s payments service became capturePayment: you ask the agent to harden the capturePayment path in src/payments/processor.ts with more tests under tests/. It writes a test, runs npm test, reads the failure, edits, runs npm test again, and so on. In acceptEdits mode (the permission mode that auto-applies file edits inside your working directory; the mode-ladder lesson shows how to cycle into it) the edits fly, but every test run still stops and asks, because acceptEdits deliberately does not cover arbitrary shell commands. The mode was a bulk loosening. What you want here is a surgical one: silence this one trusted command and nothing else.
An allow rule retires a repeated prompt
Section titled “An allow rule retires a repeated prompt”An allow rule is a settings entry that moves one specific action from ask to allow within its configured scope. The quickest way to create one is at the moment the prompt appears; Claude Code may offer to remember your answer. Illustrative exchange:
⏵ Run npm test 1. Yes 2. Yes, and don't ask again for `npm test` ← creates the allow rule 3. No
> 2
✓ Added allow rule: Bash(npm test). Won't ask again.From here on, npm test runs without a new prompt wherever the rule applies. Inspect the /permissions command (typed in the session) to see which settings file, yours or the project’s, owns the rule. You can also write a project rule by hand and commit it so the team shares it:
{ "permissions": { "allow": ["Bash(npm test)", "Bash(npm run build)"] }}The discipline that keeps this safe is to allow narrowly. Bash(npm test) is a precise, low-risk command and a fine thing to silence. A blanket Bash(*) that green-lights any shell command hands the agent an unsupervised shell, exactly the thing the permission system exists to prevent. Allow the specific commands you would run a hundred times without thinking, provided they are reversible rather than destructive; leave everything else to prompt. Rule patterns support more than exact strings - prefixes, arguments, and tool-specific forms - and the current syntax lives in the permissions docs.
Where that discipline gets tested is not the rule you write calmly into a settings file. It is the prompt that arrives mid-flow, after a streak of easy yeses. The session below walks into exactly that moment: routine prompts, a narrow grant for the test command, then a destructive command arriving on the same reflex. When playback pauses, the prompt is yours, and each answer changes your standing policy by a different amount - allow-once not at all, since it covers only that single command run; a wildcard “always allow” outlives the moment, and deny-and-redirect is the cheapest correction. The session is generic, labels included: the replay presumes the acceptEdits posture this page opened with, so its in-repo edits run without asking, and the Claude Code spelling of its commands is the Bash(...) form above.
Running shell yourself, inline with !
Section titled “Running shell yourself, inline with !”There is a neighbor to this worth knowing, because it solves a related friction. Sometimes you want to run a command and put its output in front of the agent - check what is failing, look at git status, list a directory - without leaving the session or waiting for the agent to do it. In the CLI, prefix a line with ! and it runs in your shell immediately, with the result dropped into the conversation. Illustrative:
> !npm test 2>&1 | tail -20
⎿ FAIL tests/payments.test.ts - expected 200, got 500 (output added to context)
> that 500 is the bug - the capture path is missing the auth header. fix it.That ! is you running the command, not an agent tool call waiting for permission, so no allow rule is involved. It is the quickest way to put concrete output in the conversation. The inline ! is a CLI feature; other clients may require their integrated terminal.
With edits auto-applied, trusted commands running silently, and a way to drop in a command whenever you want, the leash is about as loose as is comfortable while you still review the direction. That is precisely when you need the opposite move: something the agent cannot do, however relaxed the rest of the session gets. Lock the secrets out with a deny rule.