
Custom commands in Claude Code — /roast, ready to copy
Skills are custom slash commands for Claude Code. Here's one worth having immediately: /roast — complete file, ready to copy.
Claude Code has a feature most people overlook: Skills. Custom slash commands you write yourself. It sounds technical, but it isn't. It's basically a text file that tells Claude what to do — and you call it with a short command.
What is a Skill?
A Skill is a Markdown file. Put it in the right place, and Claude Code automatically turns it into a slash command.
$ /your-command-nameThat's it. No code, no setup, no build step.
The file contains instructions — as detailed or as brief as you need. What Claude should do, in what order, what the output should look like. Everything at once, written once.
Two locations, two purposes
There are two places where Skills can live:
Project Skills go in .claude/commands/ in your repo root. They only apply to that project. You can check them into git — then every developer on the team has the same commands.
Global Skills go in ~/.claude/commands/ on your machine. They work in every project, wherever you are.
One question is enough: would this skill also work in a repo you've never seen before?
Yes → ~/.claude/commands/ — it only needs Git, nothing project-specific.
No → .claude/commands/ — it knows your stack, your files, your conventions.
A project skill: /audit
This blog has an /audit command. Every time it's called, it checks the same things: build, TypeScript, translations (the blog is bilingual), images, components, security — and commits at the end if needed.
The skill knows the stack: Next.js, next-intl, pnpm. It knows that messages/de.json and messages/en.json must stay in sync. It knows which image attributes are required.
All of that knowledge lives in the file. When I type /audit, it runs the whole thing — without me having to explain anything.
That wouldn't be possible without a skill, because too much context is required. And without a project skill, the command wouldn't make it into the repo where it applies to everyone.
The audit.md is intentionally not included here as a copy-paste file — it's too specific to this stack: Next.js, pnpm, next-intl, specific image paths. That's exactly the point. A project skill should know what only you know. You can copy the global skills directly; the project skill you write yourself.
A global skill: /roast — the most honest code review you will ever get
Ask someone to look at your code without any diplomatic filter — and actually listen to what comes back.
/roast collects material first: the last twenty commit messages, TODOs and FIXMEs in the codebase, the largest files, README quality, CI pipelines, and test coverage. Then Claude writes a single piece of connected, precisely sarcastic — but fair — commentary on what it finds.
Clean repos aren't a problem: if there's nothing obvious to criticise, the skill looks for the one thing that's still off — or comments on what's conspicuously missing.
Here's the complete file — put it at ~/.claude/commands/roast.md:
---
description: Delivers a personalised, funny but accurate roast of your codebase — git history, code quality signals, and project structure distilled into sharp prose.
argument-hint: [de]
---
# /roast — Codebase Roast
You are a sarcastic but warm code critic. Your goal: roast this codebase so accurately and entertainingly that the developer laughs and immediately wants to open a refactor branch.
## Step 1 — Gather material
Run these commands and note what you find:
1. `git log --format="%ar: %s" --no-merges -20` — last 20 commits with relative age and message
2. `git log --since="30 days ago" --no-merges --oneline | wc -l` — commit frequency over the last 30 days
3. `git stash list --format="%gd (%cr): %gs"` — stash entries with age
4. `grep -rE "TODO|FIXME|HACK|XXX" --include="*.ts" --include="*.tsx" --include="*.js" --include="*.jsx" --include="*.py" --include="*.go" --include="*.rb" . 2>/dev/null | grep -v "/node_modules/" | grep -v "/.next/" | grep -v "/dist/" | wc -l` — total technical debt comments
5. `grep -rlE "TODO|FIXME|HACK|XXX|console\.log|@ts-ignore|eslint-disable" --include="*.ts" --include="*.tsx" --include="*.js" --include="*.jsx" --include="*.py" --include="*.go" --include="*.rb" . 2>/dev/null | grep -v "/node_modules/" | grep -v "/.next/" | grep -v "/dist/" | head -10` — files with technical debt markers
6. `find . \( -name "*.ts" -o -name "*.tsx" -o -name "*.js" -o -name "*.py" -o -name "*.go" \) -not -path "*/node_modules/*" -not -path "*/.next/*" -not -path "*/dist/*" -exec wc -l {} + 2>/dev/null | sort -rn | head -6` — largest source files
7. `cat README.md 2>/dev/null || echo "[No README found]"` — README quality
8. `ls -1 && echo "---" && ls -1 | wc -l` — root directory contents and count
9. `ls .github/workflows/ 2>/dev/null && echo "[CI found]" || echo "[No CI found]"` — CI pipelines
10. `cat package.json 2>/dev/null | grep -A5 '"scripts"' | grep -iE "test|spec|jest|vitest|playwright" || echo "[No test scripts found]"` — test setup
11. `find . \( -name "*.test.*" -o -name "*.spec.*" -o -name "__tests__" \) -not -path "*/node_modules/*" -not -path "*/.next/*" | wc -l` — test file count
## Step 2 — Calibrate the roast
Before writing, assess the overall state:
**If the repo has obvious problems** (bad commit messages, high TODO count, giant files, no README, no CI, no tests): roast those directly. Be specific.
**If the repo looks clean** (good commits, low debt, reasonable file sizes): don't manufacture problems that aren't there. Instead:
- Find the one thing that IS off — there's always something
- Note what's conspicuously absent: tests exist but no CI, CI exists but no tests, README exists but hasn't been touched in years
- Observe the gap between ambition and reality: what does the commit history suggest this project wants to be, and how close is it?
- A suspiciously clean repo is itself worth commenting on
## Step 3 — Write the roast
Deliver the roast as flowing prose — no bullet points, no headers. One to three paragraphs.
Draw from your findings specifically:
- Quote bad commit messages verbatim. `fix`, `fix2`, `wip`, `asdf` are fair game.
- If there are 50 TODOs, calculate what percentage will realistically ever be addressed. Round down aggressively.
- If a file exceeds 600 lines, name it. Ask what it is doing with its life.
- If the last commit was weeks ago, enquire about the developer's wellbeing.
- If there is no README, or it is three lines long, have an opinion about this.
- Stash entries older than a month deserve a mention.
- Root clutter: judge relative to repo type — 15 config files in a small project is a lifestyle choice.
- No CI: note it. CI exists but no tests: note the theatrical commitment to automation.
- Many test files but `console.log` and `@ts-ignore` everywhere: observe the contradiction.
Tone: sarcastic, precise, fond. The goal is "okay, that's fair" — not "this is personal".
Output language: if `$ARGUMENTS` is `de`, write in German. Otherwise match the language of the README or the most common code comments — default to English if unclear.
Length: 150–250 words. Brevity sharpens the wit.
## Step 4 — The Quick Fix
Close with a single "Quick Fix": the most embarrassing thing that could be addressed in under ten minutes. Name it exactly — file name, commit message, count, whatever is most specific. If the repo is genuinely clean, the Quick Fix should be the one thing that would make it undeniably better.Create the file — in a terminal:
mkdir -p ~/.claude/commands
nano ~/.claude/commands/roast.mdThen in any git repo:
/roast # English (default)
/roast de # German
What skills actually save
What skills really save is explanation. Without a skill, you type something like: "Look at the git log, check for TODOs, write a sarcastic but fair comment about what you find." Claude asks a follow-up. You answer. It refines. Three or four messages for something that's always the same.
The skill stores this prompt permanently. One line instead of four messages — and the output is more consistent because the instructions don't vary from day to day.
Creating Skills — the two commands
Global:
mkdir -p ~/.claude/commands
# Write your skill, e.g. roast.mdProject:
mkdir -p .claude/commands
# Write your skill, e.g. audit.md
# git add .claude/commands/audit.mdThe filename becomes the command name. roast.md → /roast. code-review.md → /code-review.
What's worth building
A few ideas that make sense immediately:
Global:
/roast— as above. Drop the file once, use it in every repo./commit— no more "fix" as a commit message. Claude reads the diff and writes Conventional Commits./explain— get selected code explained in words you can paste straight into documentation.
Project:
/audit— build, tests, types, conventions in one call. Not ten messages./review— code review following rules only you know. No re-explaining the stack next time./deploy-check— a pre-production checklist that never gets skipped because it lives in the repo.
Start with /roast: drop the file, use it in any git repo. What comes up on the first run is usually something you'd stopped seeing — because you'd been too close to it.


