Appearance
Custom Commands for Project Management
Think about the last time you typed the same thing into Claude Code for the fifth time. Maybe it was the review prompt you use before merging: "Read every changed file, check it against the existing patterns in the codebase, flag anything that looks inconsistent or incomplete." Maybe it was the deploy sequence: "Run the tests, build the Docker image, push to the registry, and update the server." You typed those instructions, watched the agent execute them, and somewhere in the back of your mind you thought: "I should find a way to reuse this."
That is what custom slash commands are for. They turn a paragraph you retype into a command you invoke: /review, /deploy, /spec. One character at the start of a line, and the agent runs a workflow you designed once and perfected over time.
What you'll learn
- Custom slash commands turn repeated multi-step prompts into instant, reusable workflow tools —
/spec,/review,/deploy, and anything else your project needs - Commands live in
.claude/commands/as Markdown files with YAML frontmatter for metadata and a body for the prompt - Each command is a project management tool: it encodes a specific workflow (spec generation, code review, deployment) that the agent follows consistently every time
- Commands compound over the life of a project — the first one saves 30 seconds, the fifth one saves an hour, and the set of them becomes your project's operating manual
The problem: you are a human copy-paste machine
Vibe coding moves fast. You describe a feature, the agent builds it, you review the output, you ship. The bottleneck is rarely the coding. The bottleneck is everything around the coding: checking that the output matches what you intended, running the test suite, making sure no security issues crept in, deploying to production, writing up the summary for your team.
Every one of these steps is a task you can describe to the agent. But describing the same thing five times a day is waste. It is also error-prone — the fourth time you write the review prompt, you might forget to mention edge case checking. The sixth time, the agent might interpret it differently because you phrased it slightly differently.
The solution is to write the prompt once, test it until it works reliably, and then invoke it with a slash command. /review instead of "Read every changed file, check it against..." — three characters instead of three paragraphs, and the agent gets the exact same instructions every time.
Options & when to use each
| Approach | What it is good for | What it costs you | When to pick it |
|---|---|---|---|
| One-off prompts | Quick tasks you do once | Inconsistent results; repeated typing; forgotten steps over time | Genuine one-off requests that you will never need again |
| Custom slash commands | Repeated workflows that follow the same pattern every time | Upfront time to write and test the command; maintenance when the workflow changes | Any workflow you run more than twice — spec generation, code review, deployment, testing, scaffolding |
| Shell scripts | Tasks that do not need LLM reasoning — deterministic builds, file operations, data transforms | No ability to reason about code; breaks when the codebase structure changes | Purely mechanical tasks where the output is always the same for the same input |
| CI/CD pipelines (GitHub Actions, etc.) | Tasks that need to run on every push or merge, unattended | Slower feedback loop; harder to iterate; overkill for per-session workflows | Automated gates — testing, linting, security scanning — not interactive development workflows |
Custom slash commands occupy a specific niche: workflows that involve LLM reasoning about your codebase, that you run repeatedly, and that you want to be consistent. They are not for deterministic shell commands (use shell scripts) and not for automated CI gates (use pipelines). They are for the things a senior developer on your team would do — review code, generate specs, plan tasks — that you want the agent to do the same way every time.
Build it: three commands that run your project
We will build the three commands that form the backbone of a vibe-coded project: /spec to convert a feature description into a development plan, /review to audit code before merging, and /deploy to ship changes. Each one is a standalone tool. Together they become your project management system.
Step 1: create the commands directory
bash
cd ~/projects/my-app
mkdir -p .claude/commandsClaude Code looks for .claude/commands/ relative to your project root. Any Markdown file in that directory becomes a slash command.
Step 2: /spec — generate a spec from a description
Create .claude/commands/spec.md:
markdown
---
description: Generate a specification from a feature description
argument-hint: Feature description
---
You are generating a specification document for a vibe-coded feature. Read the existing codebase first to understand the conventions, then produce a spec.
The specification must include:
1. **What it builds** — the feature, in concrete terms. What the user sees, what the API returns, what the database stores. No implementation details yet.
2. **What it does NOT build** — explicit scope boundaries. "This spec does not cover user authentication." "This spec does not cover email notifications." This is the most important section for keeping the agent on track.
3. **The contract** — inputs, outputs, and behavior that other parts of the system can depend on. Route paths, API response shapes, database schema changes, file locations.
4. **Edge cases** — the situations that might break a naive implementation. Empty inputs, missing data, concurrent requests, very large datasets, authentication failures.
5. **Acceptance criteria** — specific, testable statements. "A GET request to /api/reports?month=2026-08 returns a JSON array of revenue by category." Not "The reports page works."
Write the spec to `specs/<feature-name>.md`. The filename should be a short slug derived from the description.
The feature to spec: $ARGUMENTSThe $ARGUMENTS placeholder receives whatever text follows /spec. The frontmatter gives Claude Code metadata: a description shown in the command list, and an argument hint so you know what to type after the command name.
Test it:
bash
claude
> /spec Monthly revenue report with category filters and CSV exportClaude Code reads the existing codebase (because the command body says "Read the existing codebase first"), generates a spec, and writes it to specs/monthly-revenue-report.md. You now have a specification you can review, edit, and then feed to the agent in a subsequent session.
Step 3: /review — audit code against the spec
Create .claude/commands/review.md:
markdown
---
description: Review staged changes for quality, consistency, and security
model: claude-sonnet-4-5
---
You are performing a code review on vibe-coded changes. Do not make any edits. Produce a structured review report.
Review the staged changes at `!git diff --staged` against these criteria:
1. **Spec alignment** — does the code match the spec in `specs/`? If no spec exists for these changes, note that as a finding.
2. **Convention adherence** — does it follow the patterns in CLAUDE.md and the existing codebase? Flag any imports, naming, or patterns that break from the established conventions.
3. **Completeness** — are there stub functions, TODO comments, or missing error handling? Flag anything that looks unfinished.
4. **Edge cases** — test the logic against empty inputs, null values, concurrent access, and boundary conditions. Flag any case where the code would fail silently.
5. **Security** — check for hardcoded secrets, unsanitized user input in SQL, missing authentication checks, or exposed internal details.
Format the report as:
- **Overall**: PASS (ready to merge), CHANGES REQUESTED (fixes needed), or NEEDS REVIEW (ambiguous, requires a human decision)
- **Critical issues**: things that will break in production
- **Warnings**: things that work but could cause problems later
- **Suggestions**: improvements that are not required but would make the code better
Write the report to `reviews/<branch-name>-<date>.md`.This command uses !git diff --staged (the ! syntax runs a shell command and captures the output) to get the actual diff. It also specifies a model in the frontmatter — use a fast model for review so the feedback loop stays tight.
Test it:
bash
git add -A
claude
> /reviewThe agent reads the staged diff, cross-references the spec, checks conventions, and writes a review report you can read before merging. You are not reviewing code line by line anymore — you are reviewing the review, which is much faster.
Step 4: /deploy — ship changes
Create .claude/commands/deploy.md:
markdown
---
description: Run the full deploy pipeline: test, build, push, ship
argument-hint: Deploy environment (production|staging)
---
You are executing the deployment pipeline for a vibe-coded project. Run each step and report the result. Stop on any failure.
1. **Run the test suite**: `!pytest -v`
2. **Check the spec**: if a spec exists in `specs/` for the current changes, verify the code matches it. If not, proceed with a warning.
3. **Build**: `!docker build -t my-app:latest .`
4. **Tag and push**: `!docker tag my-app:latest registry.example.com/my-app:latest && docker push registry.example.com/my-app:latest`
5. **Deploy**: SSH into the server and restart the service. `!ssh deploy@server.example.com 'cd /opt/my-app && docker compose pull && docker compose up -d'`
6. **Verify**: curl the health endpoint. `!curl -s -o /dev/null -w "%{http_code}" https://my-app.example.com/health`
Environment: $ARGUMENTS (defaults to staging if not specified)You will customize the build, push, and deploy steps for your own infrastructure. The pattern is what matters: a linear pipeline, each step gated on the previous one, with a health check at the end. The agent runs it, reports each result, and either completes the deploy or tells you exactly which step failed.
Step 5: make your own commands
These three commands — /spec, /review, /deploy — are the backbone, but the real value comes from the commands you build for your specific project. Here are three that every project eventually needs:
/new-feature — combines /spec and a scaffold step, generating a spec and then creating the starter files so the agent has a target to aim at.
/scaffold — generates a new route, template, and test file from a description, using the conventions in CLAUDE.md so everything lands in the right place.
/audit — a deeper review focused on a specific concern: security, performance, accessibility, or database query efficiency. Different from /review which is a general pre-merge check.
The template for any command:
markdown
---
description: What this command does, shown in the command list
argument-hint: What to type after the command name (optional)
model: Which model to use (optional, defaults to your configured model)
allowed-tools: Comma-separated list of allowed tools (optional, for security)
---
Your prompt body. Use `$ARGUMENTS` for whatever the user typed after the command name. Use `!shell command` to run a command and capture its output. Use `@path/to/file` to inject a file's contents into the prompt.What goes wrong
| Mistake | How you notice it | The fix |
|---|---|---|
| Command body is too vague ("Review the code and tell me if it is good") | The review output is generic — the agent says "looks good" but misses the SQL injection in line 47 | Be specific about what to check. "Check every user input for SQL injection" produces different results than "review for security" |
| Command does not read the codebase first | The agent makes recommendations that contradict how the codebase actually works | Start every command that reasons about code with "Read the existing codebase first" or inject the relevant files with @ |
| Command does not produce output in a standard location | Your review reports land in three different directories, and you can never find last week's report | Every command that produces a file should specify exactly where: reviews/, specs/, deploy-logs/ |
| Command tries to do too much in one step | The deploy command fails at step 4 and you have no idea which of the earlier steps actually completed | Gated pipeline: each step reports success or failure, and the command stops on the first failure. No "run everything and hope" |
$ARGUMENTS does not work | The output contains the literal text $ARGUMENTS instead of your input | Check spelling: it is $ARGUMENTS (all caps, with S). For positional arguments, use $1, $2 |
| Command references absolute paths | You move the project and every command breaks because /home/you/old-project/specs/ does not exist anymore | Use relative paths: specs/, reviews/, ., always relative to the project root |
Confirm it worked
Run /spec "Test feature for command verification". Confirm that a file lands in specs/test-feature-for-command-verification.md with all five sections: what it builds, what it does not build, the contract, edge cases, and acceptance criteria. If any section is missing, the command body is not specific enough.
Stage some changes with git add -A, then run /review. Confirm the agent reads the staged diff (you will see the actual diff in its reasoning), references CLAUDE.md or spec files if they exist, and writes a report to reviews/. A report that says "everything looks fine" without citing specific lines is a failure — your command needs more specific instructions.
Run /deploy staging. The agent should run the test suite, build, push, deploy, and health check in sequence. If any step fails, the agent should report exactly which step failed and stop.
The real confirmation is not these tests. It is what happens three weeks from now when you type /review on a Friday afternoon before leaving for the weekend, and the agent catches a bug you would have shipped. Every time a command prevents a problem instead of just describing one, you have built a tool worth keeping.
Next: Spec-Driven Development