Script automation transforms Claude Code from an interactive assistant into a powerful automation engine. By combining hooks, custom commands, headless mode, and scripting patterns, you can automate everything from code formatting to large-scale migrations. This guide reveals how to build automation workflows that run autonomously while maintaining the flexibility to intervene when needed.
Hooks are Claude Code’s secret weapon for automation. They’re shell commands that execute automatically at specific points in Claude’s lifecycle, turning repetitive manual tasks into seamless background operations.
Hook Events
The hook system provides five strategic intervention points:
PreToolUse : Before Claude executes any tool/command
PostToolUse : After a tool/command successfully completes
UserPromptSubmit : When you submit a prompt to Claude
Notification : When Claude sends a notification
Stop : When Claude finishes its response
Let’s start with the most common automation: automatic code formatting.
Create the hooks configuration
Add to .claude/settings.json
"command" : " prettier --write \" $CLAUDE_FILE_PATHS \" "
Test the hook
# Ask Claude to create a messy JavaScript file
claude " Create a test.js file with unformatted code "
# The file will be automatically formatted after creation!
"command" : " if [[ \" $CLAUDE_FILE_PATHS \" =~ \\ .(ts|tsx)$ ]]; then npx prettier --write \" $CLAUDE_FILE_PATHS \" ; elif [[ \" $CLAUDE_FILE_PATHS \" =~ \\ .py$ ]]; then black \" $CLAUDE_FILE_PATHS \" ; elif [[ \" $CLAUDE_FILE_PATHS \" =~ \\ .go$ ]]; then gofmt -w \" $CLAUDE_FILE_PATHS \" ; fi "
"command" : " if [[ \" $CLAUDE_FILE_PATHS \" =~ \\ .(ts|tsx)$ ]]; then npx tsc --noEmit --skipLibCheck \" $CLAUDE_FILE_PATHS \" || echo '⚠️ TypeScript errors detected - please review'; fi "
"command" : " if [[ \" $CLAUDE_FILE_PATHS \" =~ \\ .(js|ts|py)$ ]]; then semgrep --config=auto \" $CLAUDE_FILE_PATHS \" || echo 'Security scan complete'; fi "
Hooks receive rich context through environment variables:
$CLAUDE_FILE_PATHS # Space-separated list of affected files
$CLAUDE_SESSION_ID # Unique session identifier
$CLAUDE_TOOL_NAME # Name of the tool being executed
$CLAUDE_USER_PROMPT # The original user prompt
"hookEventName" : " PostToolUse " ,
"sessionId" : " uuid-here " ,
"filePaths" : [ " src/index.ts " ],
Custom slash commands turn complex automation workflows into simple, parameterized commands. They’re stored as Markdown files and can be shared across your team.
Create the commands directory
mkdir -p .claude/commands
Create your first command (.claude/commands/test.md
)
Please create comprehensive tests for: $ARGUMENTS
- Use our standard testing framework
- Include unit and integration tests
- Mock external dependencies
- Test error cases and edge conditions
- Achieve at least 80% coverage
- Place tests in __ tests __ directory
- Follow our naming convention: *.test.ts
Use the command
# Claude generates comprehensive tests for UserService
Migration Command
Migrate $ARGUMENTS from our old API to the new API:
1. Find all usages of the old API
2. Update imports to use new package
3. Transform method calls to new syntax
4. Update any type definitions
5. Run tests to verify migration
6. Create a migration report
Security Audit
Perform security audit on: $ARGUMENTS
- Check for SQL injection vulnerabilities
- Scan for XSS possibilities
- Review authentication flows
- Check for exposed secrets
- Verify input validation
- Generate security report
Performance Analysis
Analyze performance of: $ARGUMENTS
- Profile the code execution
- Review algorithm complexity
Documentation Generator
Generate documentation for: $ARGUMENTS
- Create comprehensive docstrings
- Generate API documentation
- Update README if needed
For larger teams, organize commands hierarchically:
│ ├── migrate.md # /backend:migrate
│ ├── optimize.md # /backend:optimize
│ └── test.md # /backend:test
│ ├── component.md # /frontend:component
│ ├── style.md # /frontend:style
│ └── test.md # /frontend:test
├── deploy.md # /devops:deploy
└── monitor.md # /devops:monitor
Headless mode enables Claude Code to run in non-interactive environments, perfect for CI/CD automation.
claude -p " Fix all linting errors " --output-format stream-json
# With specific tools allowed
claude -p " Update dependencies " --allowedTools " Edit Bash(npm:*) "
# Verbose mode for debugging
claude -p " Run security audit " --verbose
- uses : actions/checkout@v4
- uses : actions/setup-node@v4
- name : Install Claude Code
run : npm install -g @anthropic-ai/claude-code
claude -p "Review the changes in this PR for:
- Security vulnerabilities
--output-format stream-json > review.json
- name : Post Review Comment
uses : actions/github-script@v7
const review = require('./review.json');
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
# Run Claude Code to check staged files
staged_files = $( git diff --cached --name-only )
if [ ! -z " $staged_files " ]; then
claude -p " Check these files for issues: $staged_files
- Look for console.log statements
- Check for commented out code
- Verify no secrets are exposed
Report any issues found " \
--output-format stream-json | jq -r ' .content '
# Exit with error if issues found
echo " Pre-commit check failed. Please fix issues before committing. "
Fanning Out Pattern
Use this pattern for processing many files independently:
find src/components -name " *.jsx " > components.txt
echo " Migrating $file ... "
claude -p " Convert $file from class component to functional component with hooks.
Return 'OK' if successful, 'FAIL' if not possible. " \
--allowedTools " Edit Read " \
--output-format stream-json | jq -r ' .status '
Pipeline Pattern
Chain Claude Code with other tools:
# Analyze logs and send alerts
tail -f /var/log/app.log | \
claude -p " Monitor this log stream. If you see any errors or anomalies,
output a JSON object with severity and message " \
--output-format stream-json | \
jq -c ' select(.severity == "high") ' | \
# Send to alerting system
curl -X POST https://alerts.example.com/webhook \
-H " Content-Type: application/json " \
Run multiple Claude instances for massive parallelization:
# Create work directories
git worktree add " ../refactor- $i " " refactor-branch- $i "
# Launch parallel Claude instances
tmux new-session -d -s refactor-1 ' cd ../refactor-1 && claude -p "Refactor authentication module" '
tmux new-session -d -s refactor-2 ' cd ../refactor-2 && claude -p "Refactor user management" '
tmux new-session -d -s refactor-3 ' cd ../refactor-3 && claude -p "Refactor payment processing" '
tmux new-session -d -s refactor-4 ' cd ../refactor-4 && claude -p "Refactor notification system" '
watch -n 5 ' tmux list-sessions '
Automate changes across multiple services:
services = ( " user-service " " order-service " " payment-service " " notification-service " )
for service in " ${ services [ @ ] } " ; do
echo " Updating $service to API $new_version ... "
cd " ../ $service " || continue
claude -p " Update this service to use API $new_version :
1. Update client library to $new_version
2. Modify all API calls to use new endpoints
3. Update request/response types
5. Commit with message: 'chore: update to API $new_version '
" --allowedTools all --dangerously-skip-permissions
git push origin " api-update- $new_version "
# Create PR for all services
gh pr create --title " Update all services to API $new_version " \
--body " Automated update of all services to use API $new_version "
Automate security and compliance checks:
"matcher" : " UserPromptSubmit " ,
"command" : " ./scripts/compliance-check.sh \" $CLAUDE_USER_PROMPT \" "
"command" : " ./scripts/security-scan.sh \" $CLAUDE_FILE_PATHS \" "
Automatically maintain documentation:
Prepare release $ARGUMENTS :
1. Generate changelog from git commits
2. Update version numbers in all files
3. Generate API documentation
4. Update SDK documentation
5. Create migration guide if needed
6. Generate release notes
8. Build and test release artifacts
Use our standard templates and follow semantic versioning.
Track Claude Code usage for insights:
\" timestamp \" : \" $( date -u +%Y-%m-%dT%H:%M:%SZ ) \" ,
\" session_id \" : \" $CLAUDE_SESSION_ID \" ,
\" tool \" : \" $CLAUDE_TOOL_NAME \" ,
\" files \" : \" $CLAUDE_FILE_PATHS \" ,
\" project \" : \" $( basename $( pwd )) \"
} " >> ~/.claude/usage.jsonl
# Send to monitoring system
if [ " $CLAUDE_TOOL_NAME " = " Stop " ]; then
# Session ended, send metrics
curl -X POST https://metrics.example.com/claude-usage \
-H " Content-Type: application/json " \
-d @~/.claude/usage.jsonl
Automation Guidelines
DO:
Start simple and gradually add complexity
Test hooks thoroughly before deploying
Use timeouts to prevent hanging processes
Log automation results for debugging
Version control your automation scripts
Share successful patterns with your team
DON’T:
Over-automate to the point of losing control
Skip validation in automated workflows
Ignore error handling in scripts
Use overly permissive tool allowlists
Forget to document your automation
When building automation workflows, consider:
Minimize context loading - Use focused prompts in headless mode
Batch similar operations - Process multiple files in one session
Cache common operations - Store results of expensive computations
Use appropriate models - Sonnet 4 for simple tasks, Opus 4 for complex reasoning
Monitor token usage - Track costs in automated workflows
Script automation in Claude Code transforms repetitive tasks into background magic. By mastering hooks, custom commands, headless mode, and automation patterns, you create workflows that handle the mundane while you focus on the creative. Start with simple formatting hooks, gradually build your command library, and soon you’ll have an automation suite that makes your entire team more productive. The key is finding the right balance – automate the repetitive, but maintain human oversight for the critical.