What this unit solvesA slash command binds a frequently-used prompt or workflow to a single
/name invocation. The key difference from a Skill: a command is triggered by you deliberately; a Skill is invoked by the model based on its own judgment. This unit covers command format, authoring, $ARGUMENTS parameter injection, and the decision criterion for choosing a command over a Skill.Learning objectives
- Explain the difference and division of responsibility between a command (user-triggered) and a Skill (model-invoked).
- Create a custom command file under
.claude/commands/or~/.claude/commands/. - Use
$ARGUMENTS,$0,$1, and named-variable syntax to give a command dynamic capability. - Use
disable-model-invocation: trueto prevent Claude from invoking a specific command on its own. - Decide whether a given requirement belongs as a command or a Skill, and state the criterion.
1. What a command is
A slash command is an encapsulated prompt you trigger by typing/name at the start of a Claude Code session. It does not depend on the model recognizing your intent — what you type is what runs (as of 2026-06, per the official commands documentation [1]).
Three key properties:
- Deliberately triggered: you don’t type it, Claude won’t suggest it. The decision is entirely yours.
- Reusable: write it once; every future invocation is identical.
- Version-controlled: files in
.claude/commands/can go into Git and be shared across the team.
2. Commands vs. Skills: deliberate vs. automatic
.claude/commands/<name>.md and a Skill (SKILL.md) now share the same underlying mechanism in Claude Code [2]. Their trigger timing differs:
| Dimension | Command | Skill |
|---|---|---|
| Trigger | User types /name | Model invokes based on description semantics |
| Default visibility | Shown in / menu; user-typed | Model-visible; user can also type /name |
| File location | .claude/commands/<name>.md or ~/.claude/commands/<name>.md | .claude/skills/<name>/SKILL.md or ~/.claude/skills/<name>/SKILL.md |
| Name collision | If a skill and a command share a name, the skill wins [2] | Same |
| Right fit | ”I know I want to do X right now" | "Let the model judge when to do X” |
- High certainty, fixed workflow → command.
- Has side effects, you don’t want the model deciding when to run it (deploy, send message, commit) → command +
disable-model-invocation: true. - Should depend on reading user intent (code review, doc search, refactor suggestions) → Skill.
3. Authoring: file location and structure
File locations (as of 2026-06):| Location | Scope |
|---|---|
~/.claude/commands/<name>.md | All projects |
./.claude/commands/<name>.md | Current project; shared with the team via version control |
<plugin>/commands/<name>.md | Available within an enabled plugin |
/: .claude/commands/deploy.md responds to /deploy; .claude/commands/fix-issue.md responds to /fix-issue.
3.1 Minimal form
/commit, this text is injected into Claude’s current conversation and Claude uses it to generate a commit message.
3.2 Using frontmatter to configure behavior
| Field | Purpose |
|---|---|
description | Shown in the / menu; used by Claude when evaluating semantics |
argument-hint | Autocomplete hint text, e.g. [issue-number] |
allowed-tools | Tools that need no additional confirmation when the command is active |
model | Override the model; defaults to the current session model |
disable-model-invocation: true | Prevent Claude from invoking this command on its own |
user-invocable: false | Hide from the / menu; model-only invocation |
Why
disable-model-invocation: true mattersSuppose you write a /deploy command. Without the flag, the model may see “this code looks ready to deploy” in conversation and invoke /deploy on its own — while you are still reviewing. With disable-model-invocation: true, the command only runs when you explicitly type /deploy; the model cannot see it at all. For any workflow with side effects — deploy, send, push — add this flag by default.4. Parameter injection: $ARGUMENTS and indexed syntax
When you trigger a command, everything you type after /name is injected into the command body.
Simplest approach: $ARGUMENTS
Use Typing
$ARGUMENTS to receive everything typed after /name:/fix-issue 123 replaces $ARGUMENTS with 123; Claude receives “Fix GitHub issue 123 following our coding standards. …” [2].If the command body contains no $ARGUMENTS, Claude Code appends the arguments as ARGUMENTS: <your input> at the end of the body — Claude still sees them [2].Positional index: $0, $1, $2
To split multiple arguments, use Typing
$0, $1, $2, or $ARGUMENTS[0]:/migrate-component SearchBar React Vue gives $0 = SearchBar, $1 = React, $2 = Vue.Wrap multi-word arguments in quotes: /migrate-component "Search Bar" React "Vue 3".4.1 Other available variables
| Variable | Purpose |
|---|---|
${CLAUDE_SESSION_ID} | Current session ID; useful for log names or session-scoped filenames |
${CLAUDE_SKILL_DIR} | Directory containing the command/skill; use to reference co-located scripts |
${CLAUDE_EFFORT} | Current effort level (low / medium / high / xhigh / max) |
5. Dynamic context injection: !`command`
Command body content can use !`shell command` to execute a shell command before the body is sent to Claude and embed its output inline [2]:
!`cmd` in sequence, substitutes the output, and only then passes the entire body to Claude as a prompt. From Claude’s perspective it receives plain text that already contains the git diff output.
Multi-line commands use the fenced code block form:
6. Tool comparison
| Concept | Anthropic Claude (primary) | OpenAI Codex | GitHub Copilot | Cursor |
|---|---|---|---|---|
| Custom command location | .claude/commands/<name>.md, ~/.claude/commands/<name>.md | config.toml configuration [source unconfirmed: Codex custom slash command path as of 2026-06] | .github/prompts/<name>.prompt.md (prompt files) | .cursor/commands/<name>.md |
| Parameter injection syntax | $ARGUMENTS, $0, $1, named variables | No equivalent ARGUMENTS syntax | Structured frontmatter fields | $ARGUMENTS-style variables |
| Global vs. project scope | ~/.claude/commands/ vs. .claude/commands/ | ~/.codex/prompts/ vs. .codex/prompts/ | Separate global and project files | Global User Rules + project .cursor/rules/ |
| Trigger | User types /name | User types | User types | User types |
| Prevent model auto-invocation | disable-model-invocation: true | (mechanism differs significantly) | (mechanism differs significantly) | (mechanism differs significantly) |
Naming clarificationCommands and Skills share the same underlying mechanism in Claude Code: as of 2026-06 both are unified, and both
.claude/commands/<name>.md and .claude/skills/<name>/SKILL.md produce a /name command [2]. The difference is that the former is a single file while the latter is a directory (including references/ and scripts/; see 04-4 Skills). This unit focuses on the “user-triggered” face shared by both. OpenAI Codex, GitHub Copilot, and Cursor each have a “prompt file” or “prompt template” concept, but the paths and mechanisms differ significantly; the common denominator is “prompt files support $ARGUMENTS-style variables” — consult each vendor’s current documentation for details.7. Hands-on exercises
30-minute practice
- Write a
/commitcommand: includedisable-model-invocation: trueandallowed-tools: Bash(git *)in the frontmatter; use!`git diff --cached`and!`git log --oneline -10`to pull in the staged diff and recent commit style, then ask Claude to output a Conventional Commits message. - Create a global command: write
~/.claude/commands/weekly-review.mdthat uses$ARGUMENTSto receive your focus topic; start a new project session and confirm/weekly-reviewworks across projects. - Test the misfire guard: write a
/deploy-prodcommand deliberately withoutdisable-model-invocation; mention “looks like it’s ready to deploy” in conversation and observe whether Claude invokes it on its own. Then adddisable-model-invocation: true, repeat the same sentence, and confirm Claude no longer self-triggers.
8. Common pitfalls
Self-check
The bar for passing this unit
- Can you state the fundamental difference between a command and a Skill? (The trigger subject differs.)
- Can you write a command that accepts
$ARGUMENTSin under five minutes? - Can you identify which commands should carry
disable-model-invocation: true? - Do you have a prompt you type three or more times a week? Should it be a command or a Skill? State your criterion.
Sources and further reading
Factual claims are grounded in official documentation; fast-changing items are annotated as of 2026-05.- [1] Anthropic, “Commands,” code.claude.com, 2026. [Online]. Available: https://code.claude.com/docs/en/commands (as of 2026-06; covers built-in and custom commands)
- [2] Anthropic, “Extend Claude with skills,” code.claude.com, 2026. [Online]. Available: https://code.claude.com/docs/en/skills (as of 2026-06; covers the unified command/skill mechanism,
$ARGUMENTS, and complete frontmatter reference) - [3] Anthropic, “How Claude remembers your project,” code.claude.com, 2026. [Online]. Available: https://code.claude.com/docs/en/memory (as of 2026-06;
CLAUDE.mdand modular rules)
CLAUDE.mdand auto-memory: 04-1 CLAUDE.md and memory files.- Path-scoped rules: 04-2 Rules.
- Advanced Skills (references/, scripts/, progressive disclosure): 04-4 Skills.
- Deterministic enforcement with hooks: 04-6 Hooks.