Command File Structure
Commands are markdown files in .claude/commands/ (project) or ~/.claude/commands/ (user):
.claude/
└── commands/
├── review-pr.md # /review-pr command
├── add-tests.md # /add-tests command
├── security-check.md # /security-check command
└── refactor-service.md # /refactor-service command
Writing a Slash Command
<!-- .claude/commands/review-pr.md -->
---
description: "Comprehensive PR review checking all team standards"
allowed-tools: file_read, grep, glob, bash
argument-hint: "[optional: specific files or areas to focus on]"
---
# PR Review — Team Standards Check
Review the staged changes (or $ARGUMENTS if specified) against our team standards.
Check ALL of the following:
## 1. Repository Pattern Compliance
- All database queries go through repository classes in src/repositories/
- Services never import from models directly — only through repositories
- grep for "from '../models'" in src/services/ — should be zero results
## 2. Test Coverage
- Every new public function has at least one test
- Every error path has a test
- No test files reference real external services (mock everything)
- Run: bash("pytest --cov=src --cov-report=term-missing")
## 3. Error Handling
- All async functions have try/catch or are handled by middleware
- Errors are logged before being re-raised
- User-facing error messages don't expose internal details
## 4. Security
- No credentials, tokens, or secrets in code
- All user inputs validated before use
- SQL parameters are parameterized (no string concatenation)
- Sensitive data not written to logs
## 5. Monetary Values
- All money stored as integers (cents), never floats
- Conversion happens only at API boundary
Report findings by severity: Critical / High / Medium / Low
For each finding: file, line number, issue, recommendation.
Using Arguments
The $ARGUMENTS placeholder captures text after the command name:
/review-pr src/api/payments.ts src/services/payment_service.ts
In the command file:
Review these specific files: $ARGUMENTS
Apply all team standards from our CLAUDE.md to these files only.
The allowed-tools frontmatter limits what Claude can do when this command runs:
---
allowed-tools: file_read, grep, glob
# No file_write — this command should only READ, not modify
---
---
allowed-tools: file_read, file_write, bash
# Full access — this command makes changes
---
Project vs User Commands
Project commands (.claude/commands/) — in git, shared with team:
- /review-pr
- /add-tests
- /security-check
- /generate-migration
User commands (~/.claude/commands/) — personal, not shared:
- /my-daily-setup
- /quick-debug
- /personal-review-style
Key Takeaways
- Slash commands are reusable prompt templates — one command, consistent workflow
- Project commands in
.claude/commands/ — committed, shared with team
- User commands in
~/.claude/commands/ — personal, not shared
- $ARGUMENTS for parameterized commands
- allowed-tools controls what Claude can do when the command runs
- argument-hint shows users what arguments are expected