Claude Code's custom command system allows users to define specialized workflows through markdown-based command definitions. These commands provide controlled tool access and specific instructions for Claude to follow.
Custom commands are defined as markdown files with YAML frontmatter that specify tool permissions and command descriptions.
---
allowed-tools: Bash(git checkout --branch:*), Bash(git add:*), Bash(git status:*), Bash(git push:*), Bash(git commit:*), Bash(gh pr create:*)
description: Commit, push, and open a PR
---
# Command Content (Markdown)
## Context
- Current git status: !`git status`
- Current git diff: !`git diff HEAD`
## Your task
1. Create a new branch if on main
2. Create a single commit with an appropriate message
3. Push the branch to origin
4. Create a pull request using `gh pr create`Structure Components:
! backtick syntaxThe YAML frontmatter defines command metadata and tool permissions.
---
allowed-tools:
- "Bash(git checkout --branch:*)"
- "Bash(git add:*)"
- "Bash(git status:*)"
- "Bash(git push:*)"
- "Bash(git commit:*)"
- "Bash(gh pr create:*)"
description: "Brief description of what this command does"
---Frontmatter Fields:
allowed-tools: Array of tool permissions with specific parameter patternsdescription: Brief description of the command's purpose and functionalityTool permissions use specific syntax to control what actions Claude can perform.
# Tool permission syntax patterns:
"Bash(command_pattern:*)" # Allow specific bash commands with any parameters
"Bash(git status:*)" # Allow 'git status' with any additional flags
"Bash(gh pr create:*)" # Allow GitHub PR creation with any parameters
"Bash(gh issue view:*)" # Allow viewing GitHub issues
"Bash(gh search:*)" # Allow GitHub search operations
"Bash(gh api:*)" # Allow GitHub API calls
"Read(*)" # Allow reading any file
"Write(*)" # Allow writing to any file
"Edit(*)" # Allow editing any filePermission Specificity:
* allows any parameters for the specified commandCommands can inject dynamic context using the ! backtick syntax.
## Context
- Current git status: !`git status`
- Current git diff (staged and unstaged changes): !`git diff HEAD`
- Current branch: !`git branch --show-current`
- Recent commits: !`git log --oneline -5`
- Modified files: !`git diff --name-only`Dynamic Context Features:
! are executed when the command runsClaude Code includes several pre-defined custom commands.
---
allowed-tools: Bash(git checkout --branch:*), Bash(git add:*), Bash(git status:*), Bash(git push:*), Bash(git commit:*), Bash(gh pr create:*)
description: Commit, push, and open a PR
---Functionality:
---
allowed-tools: Bash(gh issue view:*), Bash(gh search:*), Bash(gh issue list:*), Bash(gh api:*), Bash(gh issue comment:*)
description: Find duplicate GitHub issues
---Functionality:
Custom commands are stored in the .claude/commands/ directory.
# Directory structure
.claude/
└── commands/
├── commit-push-pr.md
├── dedupe.md
├── code-review.md
└── deploy.mdFile Naming Conventions:
Git Workflow Command:
---
allowed-tools: Bash(git add:*), Bash(git commit:*), Bash(git push:*)
description: Stage, commit, and push changes
---
## Context
- Modified files: !`git status --porcelain`
- Current branch: !`git branch --show-current`
## Your task
1. Review the modified files
2. Stage all changes with appropriate additions
3. Create a meaningful commit message
4. Push changes to originCode Review Command:
---
allowed-tools: Read(*), Bash(git diff:*)
description: Review recent code changes
---
## Context
- Recent changes: !`git diff HEAD~1..HEAD`
- Changed files: !`git diff --name-only HEAD~1..HEAD`
## Your task
1. Review each changed file for code quality
2. Check for potential bugs or issues
3. Suggest improvements if needed
4. Verify tests cover new functionalityDeployment Command:
---
allowed-tools: Bash(npm run build:*), Bash(npm run test:*), Bash(git tag:*)
description: Build, test, and tag for deployment
---
## Context
- Current version: !`npm version --json`
- Test status: !`npm run test`
- Build status: !`npm run build`
## Your task
1. Run full test suite and ensure all tests pass
2. Run production build and verify success
3. Create appropriate git tag for release
4. Confirm deployment readinessCustom commands handle various error scenarios:
## Error Handling Patterns
### Permission Errors
- Commands fail gracefully when attempting unauthorized tool usage
- Clear error messages indicate which permissions are missing
### Context Injection Failures
- Failed context commands are reported but don't block execution
- Partial context is provided when some commands succeed
### Task Execution Errors
- Tool failures are reported with appropriate error context
- Commands can include fallback instructions for common failure scenarios# Test command permissions
# Create a test command file and validate syntax
# Test dynamic context injection
# Verify that !`command` syntax works as expected
# Test tool restrictions
# Ensure only allowed tools can be executedMulti-step Workflows:
---
allowed-tools: Bash(git add:*), Bash(npm run test:*), Bash(git commit:*), Bash(git push:*)
description: Test-driven commit workflow
---
## Your task
1. Run tests to verify current state
2. Stage only files related to passing tests
3. Commit with test results in message
4. Push if all tests pass, otherwise report issuesConditional Logic:
## Context
- Git status: !`git status --porcelain`
- Has staged changes: !`git diff --cached --quiet; echo $?`
## Your task
Based on the context:
- If staged changes exist: commit them with appropriate message
- If no staged changes: ask user what to stage first
- If conflicts exist: guide user through resolution