In the previous BashTool chapter, we gave claudeCode the ability to run terminal commands. We described this as giving the AI "hands."
But imagine if those hands tried to delete your entire hard drive by accident.
Power requires control. This is where Shell Safety Checks come in. Before any command is actually executed by the BashTool, it must pass through a safety inspection to see if it is potentially destructive.
This module acts like a Safety Inspector at a construction site. It doesn't necessarily stop work, but it flags dangerous activities and puts up a big yellow "CAUTION" sign.
It is a logic layer that sits between the AI's request and the actual execution of the command. It analyzes the text of the command to predict if it will cause permanent data loss.
Imagine you ask claudeCode: "Start over and clean up the git history."
The AI, trying to be helpful, might decide to run:
git reset --hard HEAD~1
This command is destructive. It permanently deletes your recent work.
Without Safety Checks: The command runs, and your work vanishes instantly.
With Safety Checks: The system detects the pattern git reset --hard and pauses. It displays: "Warning: This command may discard uncommitted changes."
To understand how we catch these commands, we use two simple concepts.
We don't "understand" the command deeply like a compiler. Instead, we look for "dangerous shapes" in the text using Regular Expressions (Regex).
ls, cd, echorm, truncate, dropThis system doesn't usually block the user (you might actually want to delete files). Instead, it generates a Warning Message. This message is passed to the Ink UI Framework so it can be displayed in red or yellow text when asking for permission.
This feature is essentially a function that takes a string (the command) and returns a warning (or null).
import { getDestructiveCommandWarning } from './safety';
const command = "rm -rf ./src";
// 1. Ask the safety inspector
const warning = getDestructiveCommandWarning(command);
if (warning) {
// Output: "Note: may recursively force-remove files"
console.log("DANGER:", warning);
} else {
console.log("This command looks safe.");
}
Explanation: We pass the scary command into the function. Because it contains rm -rf, the function recognizes a destructive pattern and returns a specific warning message.
When the BashTool receives a command from the AI, the flow looks like this:
git push --force.push + --force matches a rule.Here is the visual flow:
The core of this logic is located in tools/BashTool/destructiveCommandWarning.ts. It is surprisingly simple: it is mostly a list of rules.
We create a list of objects. Each object has a pattern (what to look for) and a warning (what to say).
// tools/BashTool/destructiveCommandWarning.ts
const DESTRUCTIVE_PATTERNS = [
{
// Looks for "rm" followed by "-rf"
pattern: /(^|[;&|\n]\s*)rm\s+-[a-zA-Z]*f/,
warning: 'Note: may force-remove files',
},
{
// Looks for "git reset --hard"
pattern: /\bgit\s+reset\s+--hard\b/,
warning: 'Note: may discard uncommitted changes',
},
// ... dozens of other patterns
];
Explanation: We use Regular Expressions (the weird looking characters like \b and \s+). These allow us to match rm -rf even if there are extra spaces or flags involved.
This function simply loops through the list above.
export function getDestructiveCommandWarning(command: string) {
// Loop through every known dangerous pattern
for (const { pattern, warning } of DESTRUCTIVE_PATTERNS) {
// If the command matches the pattern...
if (pattern.test(command)) {
return warning; // Return the specific warning text
}
}
return null; // Looks safe!
}
Explanation: This is a classic "Early Return" function. The moment it finds *one dangerous thing, it stops looking and reports it. If it finishes the loop without finding anything, it returns null.*
This chapter acts as the first line of defense in our security strategy:
claudeCode is running in "Auto Mode" (without user supervision), these safety checks might automatically pause the execution to prevent the AI from doing damage while you are away from the keyboard.
You have learned that Shell Safety Checks are essentially a spell-checker for danger. By using a list of known destructive patterns (Regex), we can catch commands like rm -rf or git reset before they happen. This gives the user a chance to say "No!"
But detecting danger is only one part of security. How do we manage the overall permissions of the application? Can we restrict the AI to read-only mode?
Next Chapter: Permission & Security System
Generated by Code IQ