Claude Code slash commands: what I actually put in mine
TL;DR A Claude Code slash command isn't a shortcut — it's a decision you stopped re-explaining, and the valuable part of it is the safety rules baked inside, not the instruction.
Every time I reviewed a blog draft, I typed the same four things.
- Read the current file first, not the version in your head.
- Check every factual claim. Assume the AI made some of them up.
- Don’t rewrite my voice while you’re at it.
- And do not publish. Ever. Not until I say so.
I typed some version of that for weeks. Then I stopped. I wrote those four decisions into one file and gave it a name. Now I type /blog-review and the model already knows all of it.
That file is a Claude Code slash command. Today this blog runs on six of them — research, drafting, review, index-checking, performance, writing. This post is about what actually goes in one — not the syntax, which takes five minutes to learn, but the part that took me longer to figure out: a slash command isn’t a shortcut. It’s a decision you no longer want to explain repeatedly.
I’ll take one apart, line by line. By the end you’ll have a four-question framework you can run against your own commands.
Before I do, here’s the actual set — so “a command per repeated decision” isn’t abstract:
- /blog-keywords — research a keyword’s real demand before I write for it
- /blog-draft — turn a raw experience into a draft, and never publish it
- /blog-review — check a draft and, only on my explicit OK, publish it
- /blog-index-check — confirm a published post is actually indexed
- /blog-perf — pull the traffic numbers and decide what they mean
- /blog-write — draft or revise a post in my own voice
Six, because six map to steps I take on repeat. I’ll take the third one apart — it’s the one with a rule I couldn’t afford to get wrong.
What a slash command actually is
In current Claude Code, a slash command lives in a folder — .claude/skills/<name>/SKILL.md for me — and it’s just Markdown. Frontmatter at the top says when it should trigger. The body is instructions the model reads when you invoke it.
That’s the whole mechanism. You can learn it from the docs in one sitting.
The thing the docs won’t tell you is what to put in one. Most examples show a command that saves keystrokes: “summarize this file,” “write a commit message.” Useful, but that’s autocomplete. The commands I actually rely on don’t save typing. They save me from re-explaining a judgment I make the same way every time.
Here’s the concrete difference. “Write a commit message” is a shortcut. “Review this draft, and never let the review turn into a publish” is a decision — one I’d otherwise have to restate, correctly, every single time, or risk the model quietly shipping something.
How /blog-review actually decides — step by step, with the why
This is the command that publishes nothing until I say so. The steps matter less than the reason each one is there, so I’ll give both.
Step 1 — Read the draft from disk first. The command’s first instruction is to grep for what’s actually in the queue and open that file, not to trust the copy it remembers from earlier in the chat.
Why: drafts change between turns. Review a stale copy and every check after this one is checking the wrong text.
Step 2 — Check the factual claims, and treat that as the check that matters most. The command tells the model to treat every figure, version, and command as suspect and flag it, not to smooth out the prose. Catch the invented fact; don’t make the writing prettier.
Why: a wrong number costs more than an awkward sentence. The awkward sentence costs a reader a wince. The wrong number costs trust, and on a blog about AI tooling that’s the entire asset.
Step 3 — Require explicit approval before publishing. The model surfaces what’s wrong, I make the call, and draft: false only happens after I say “OK.” The command’s own “what it must never do” list starts with publish without my explicit approval.
Why: the review command must never become the publish command. “Review this and if it looks good, ship it” is one confident-sounding pass away from shipping something I never read.
Notice what that last step is. It’s not an instruction to the model about the task. It’s a guardrail around the model, written into the same file. That’s the part I’d have kept forgetting to say out loud.
A command is a decision you stopped re-explaining
That’s the whole idea, stated once so it sticks.
The six commands I run this blog with each exist because I found myself giving the same instructions and the same cautions on repeat. The instruction was never the hard part. The cautions were: don’t publish automatically, don’t trust the stale copy, don’t smooth over a claim you should be verifying.
So the most valuable part of a command isn’t the instruction. It’s the safety rules baked inside it. That’s also why copying someone’s SKILL.md wholesale doesn’t do much — you get their instructions without the judgment that made them shaped that way. What transfers isn’t the Markdown. It’s the decisions.
Put another way: good commands automate execution, not judgment. /blog-review automates the review — the reading, the grepping, the claim-by-claim pass. It does not automate the decision to publish. That stays mine. And to be clear about what the command does and doesn’t buy you: it doesn’t make the review faster. Reviewing a draft honestly still takes as long as it takes. What it removes is the re-explaining. The judgment is written down once instead of retyped every time.
Where it bites: too many commands, and the missing safety gate
Three ways this goes wrong, all of which I’ve hit or come close to.
Too many commands. Every command is a thing you now have to remember exists. Past a handful, you start forgetting which one does what, and you’re back to just typing instructions directly — which was the thing you were trying to stop doing. I keep six because six map to real, repeated steps. I don’t make one for something I do once.
No safety gate. The failure mode of a review command with no explicit-approval rule is obvious in hindsight: it eventually ships something on a review that only sounded thorough. The gate isn’t a nicety. It’s the reason the command is safe to run at all.
The command that quietly became the publish command. This is the specific version of the last one worth naming. If “review” and “publish” live in the same command with no wall between them, one good-looking pass ends with a live post you never read. Keeping publishing as a separate, explicit act — my “OK,” not the command’s judgment — is the single rule I’d port to any workflow that touches production.
Slash commands vs Skills — what’s the difference?
Quick one, since people search for it: in current Claude Code the two are effectively the same surface. What I’ve been calling a slash command lives as a skill — a SKILL.md with a name and a description — and typing /blog-review invokes it. The description’s job is to tell the model when to reach for it, which is why mine list natural phrases, not just the slash form: /blog-review triggers on “review,” “publish this,” “check the draft,” and the slash form alike.
So don’t get hung up on the label. Think about when it should fire and what it should decide, and you’ve written the important half of either one.
Every command should answer four questions
If you’re going to write one, this is the frame I’d use instead of copying a template. Before writing any Markdown, answer four things:
- When should it trigger? What phrasing, in the middle of real work, should make the model reach for this?
- What inputs does it expect? A file? A selection? Nothing but the current state?
- What decisions should always be made? The judgment you keep repeating — write it down here.
- What must never happen? The guardrail. This is the one people skip, and it’s the one that saves you.
A SKILL.md that answers those four is basically this:
---
name: blog-review
description: Review a draft in the queue and, only on my explicit approval,
publish it. Triggers on "review", "publish this", "check the draft".
---
# blog-review
## When this runs
Find drafts marked `draft: true`. If I named one, use that.
## What to do
1. Read the file from disk first — not the version from earlier in the chat.
2. Check every factual claim, number, and version. Assume some are wrong.
3. Show me what's questionable. Do not rewrite my voice.
## What must never happen
- Never set `draft: false` or publish without my explicit "OK".
- Never treat "the review passed" as permission to ship.
That’s not a shortcut for typing less. It’s four decisions I got tired of repeating, plus one guardrail I couldn’t afford to forget. Fill in your own four and you have a command worth keeping.
Your next command is probably already in your history
So don’t brainstorm it. The four questions tell you how to shape a command; they don’t tell you which one to write first. And guessing is how you end up with commands you made once and never use.
The pattern is invisible while you’re in it. But it’s sitting in your logs — the instructions you’ve typed over and over, the tool-flows that recur between your turns.
If you’re not sure what your first custom command should be, use this. It reads your Claude Code history, finds the workflows you keep repeating, and drafts a SKILL.md around the decisions underneath them. It runs entirely locally against ~/.claude/projects/ — nothing leaves your machine. The counting is code; deciding which repeats are real candidates, and what each one must never do, is the judgment you fill in — the same split this whole post is about.
Paste this into Claude Code to install and run it:
Fetch https://gist.githubusercontent.com/baesku789/aa323a077b313e32101e657a8d2e7bd1/raw/SKILL.md
and save it to .claude/skills/find-repeated-work/SKILL.md — then run /find-repeated-work on my history.
Or read it first: find-repeated-work on GitHub Gist.
When I ran it on mine, the top hit across 14 projects wasn’t a task at all — it was a decision I kept making: stop and lay out the options before doing anything hard to undo. That became its own command. Yours will surface something different, because it’s reading your decisions, not mine.
Don’t brainstorm your next command. Mine it from your own history.
I build these kinds of workflow systems — turning the steps you keep re-explaining to an AI into commands with the right guardrails baked in. If that’s a problem you have, get in touch.