Skip to main content
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: true to 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:
  1. Deliberately triggered: you don’t type it, Claude won’t suggest it. The decision is entirely yours.
  2. Reusable: write it once; every future invocation is identical.
  3. Version-controlled: files in .claude/commands/ can go into Git and be shared across the team.
Commands vs. pasting a promptYou can paste the same prompt repeatedly, but every time you have to trim parameters and adjust phrasing yourself. A command packages that work: you type /<name> <args> and the logic stays consistent. That consistency pays dividends wherever the output format is fixed (commit messages, PR summaries, changelogs) or for inspection workflows you run repeatedly.

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:
DimensionCommandSkill
TriggerUser types /nameModel invokes based on description semantics
Default visibilityShown in / menu; user-typedModel-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 collisionIf 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”
Simplified decision rule:
  • 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.
Workflows with side effects default to commandDeployments, pushes, Slack sends, writes to external systems — anything that is hard to undo — default to command + disable-model-invocation: true. You do not need Claude to trigger a deployment on its own because it “looks like the right time.”

3. Authoring: file location and structure

File locations (as of 2026-06):
LocationScope
~/.claude/commands/<name>.mdAll projects
./.claude/commands/<name>.mdCurrent project; shared with the team via version control
<plugin>/commands/<name>.mdAvailable within an enabled plugin
The filename is the word after /: .claude/commands/deploy.md responds to /deploy; .claude/commands/fix-issue.md responds to /fix-issue.

3.1 Minimal form

You are helping me write a commit message for the current changes. Use the project's existing commit style (Conventional Commits). Output only the commit message, no preamble.
When you trigger /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

---
description: Generate a commit message for staged changes
argument-hint: [optional context]
allowed-tools: Bash(git status *) Bash(git diff *) Bash(git log *)
model: sonnet
---

## Staged changes
!`git diff --cached`

## Recent commit style
!`git log --oneline -10`

## Task
Write a Conventional Commits message for the staged changes above.
$ARGUMENTS
Commonly used frontmatter fields (as of 2026-06, per the official Skills and commands documentation [1, 2]):
FieldPurpose
descriptionShown in the / menu; used by Claude when evaluating semantics
argument-hintAutocomplete hint text, e.g. [issue-number]
allowed-toolsTools that need no additional confirmation when the command is active
modelOverride the model; defaults to the current session model
disable-model-invocation: truePrevent Claude from invoking this command on its own
user-invocable: falseHide 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.
1

Simplest approach: $ARGUMENTS

Use $ARGUMENTS to receive everything typed after /name:
---
description: Fix a GitHub issue by number
---

Fix GitHub issue $ARGUMENTS following our coding standards.
1. Read the issue description
2. Understand the requirements
3. Implement the fix
4. Write tests
5. Create a commit
Typing /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].
2

Positional index: $0, $1, $2

To split multiple arguments, use $0, $1, $2, or $ARGUMENTS[0]:
---
description: Migrate a component from one framework to another
---

Migrate the $0 component from $1 to $2.
Preserve all existing behavior and tests.
Typing /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".
3

Named parameters

Declare arguments in frontmatter and reference them by name in the body:
---
description: Create a commit with branch and issue context
arguments:
  - branch
  - issue
---
Create a commit on branch $branch referencing issue $issue.
Typing /commit feature-x 456 gives $branch = feature-x and $issue = 456 [2].

4.1 Other available variables

VariablePurpose
${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]:
## Current changes
!`git diff HEAD`

## Status
!`git status --short`
When the command is invoked, Claude Code executes each !`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:
## Environment
```!
node --version
npm --version
git status --short
```
Two traps with dynamic injection
  1. The execution environment is your shell. When you type /deploy, !`cmd` inside the command runs in your local shell (macOS/Linux defaults to bash; Windows defaults to PowerShell, configurable [2]). Do not write sensitive operations into a command file.
  2. Org-level disable setting: organizations can set "disableSkillShellExecution": true in settings.json, replacing all dynamic injections with [shell command execution disabled by policy]. Do not rely on this mechanism for critical steps in commands destined for public repos.

6. Tool comparison

ConceptAnthropic Claude (primary)OpenAI CodexGitHub CopilotCursor
Custom command location.claude/commands/<name>.md, ~/.claude/commands/<name>.mdconfig.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 variablesNo equivalent ARGUMENTS syntaxStructured frontmatter fields$ARGUMENTS-style variables
Global vs. project scope~/.claude/commands/ vs. .claude/commands/~/.codex/prompts/ vs. .codex/prompts/Separate global and project filesGlobal User Rules + project .cursor/rules/
TriggerUser types /nameUser typesUser typesUser types
Prevent model auto-invocationdisable-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
  1. Write a /commit command: include disable-model-invocation: true and allowed-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.
  2. Create a global command: write ~/.claude/commands/weekly-review.md that uses $ARGUMENTS to receive your focus topic; start a new project session and confirm /weekly-review works across projects.
  3. Test the misfire guard: write a /deploy-prod command deliberately without disable-model-invocation; mention “looks like it’s ready to deploy” in conversation and observe whether Claude invokes it on its own. Then add disable-model-invocation: true, repeat the same sentence, and confirm Claude no longer self-triggers.

8. Common pitfalls

Anti-pattern list
  • Turning every workflow into a command: too many user-triggered invocations increase workflow friction. Use a Skill for cases where the model should judge the right time (code review, doc search).
  • Vague description: you will forget what the command does in three days. Describe the trigger condition and expected output precisely; “help me do X” is not a description.
  • Writing deploy/push/send commands without disable-model-invocation: the model may run them before you have confirmed, producing irreversible side effects.
  • Committing command files with sensitive data to a public repo: command bodies go into version control, so API keys, absolute paths, and internal URLs all leak.
  • Dynamic injection that depends on unverified state: writing !`./scripts/deploy.sh` when that script’s permissions or content are not fixed destroys reproducibility. Deterministic deployment workflows belong in a Hook (see 04-6 Hooks) or a standalone CI step.

Self-check

The bar for passing this unit
  1. Can you state the fundamental difference between a command and a Skill? (The trigger subject differs.)
  2. Can you write a command that accepts $ARGUMENTS in under five minutes?
  3. Can you identify which commands should carry disable-model-invocation: true?
  4. 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.md and modular rules)