Slash commands
What a slash command is
Section titled “What a slash command is”A slash command is a named, user-invokable shortcut. You type /<name> (or sometimes $<name>) mid-session and the CLI runs a predefined prompt, workflow, or built-in action — without you having to retype the whole thing.
Each tool ships a set of bundled commands (/model, /mcp, /diff, etc.) and lets you author your own. In Claude Code, the slash-command surface and the skills surface have largely merged in 2026 — every user-defined skill is also a slash command. In Codex, OpenCode, Cursor, and Copilot they’re still distinct primitives, though they overlap in use.
From keystroke to prompt
Section titled “From keystroke to prompt”One custom command — /security-review — traced from what you type, through the file that defines it, to the prompt the model actually receives. Watch where the arguments land (and where they can’t):
Why you’d want one
Section titled “Why you’d want one”You have an incantation. Every time you start a fresh session in this repo, you type:
“Read the latest PR description from the
releasebranch, summarise what changed, list any TODOs that have piled up, and check if there’s a migration we forgot to run.”
It’s eight lines. You’ve typed it forty times. You’ve copy-pasted it from a Notion doc thirty of those times. The other ten times you re-typed it from memory and got it slightly wrong. The instructions aren’t complex — they’re just yours, and the CLI has no way to know you keep wanting this exact thing.
A skill could pull this in when relevant, but the model has to decide it’s relevant. Sometimes you just want to say, deterministically, “run the release-check thing.” Type /release-check, the prompt gets expanded, the agent does the thing. No describing, no remembering, no waiting for the model to infer intent.
That’s the gap slash commands close: turning a thing you keep typing into a thing you keep invoking.
Real-world examples of user-defined slash commands:
- Repo-specific check-ins —
/release-check,/pre-merge,/morning-status. Same prompt, same shape, every time. - Personal habits —
/tldr(“summarise what we’ve done this session in three bullets”),/sanity-check(“look at the diff and tell me what would break in prod”). - Standardised reviews —
/security-review <file>,/perf-review <file>. Argument substitution does the targeting. - Workflow shortcuts —
/spike <idea>(“scaffold a throwaway prototype for this idea”),/ship(“run the team’s full pre-ship checklist”). - Tone or persona switches —
/skeptic(“from here on, push back hard on any decision that seems convenient”),/junior(“explain the next change as if I’ve never seen this codebase”). - Side-effect commands (Claude Code, with
disable-model-invocation: true) — things the model shouldn’t auto-trigger but you want one keystroke away:/deploy-dry-run,/db-snapshot.
The test: if it’s a prompt you’ve typed (or pasted) more than five times, it’s a slash command.
Why this and not…
Section titled “Why this and not…”| You want to… | Reach for | Not |
|---|---|---|
| Fire a predefined prompt by typing its name | Slash command | Skill |
| Have the agent reach for instructions on its own when the situation matches | Skill | Slash command |
| Inject context on every turn of every session | Rules | Slash command |
| Run automatically on a CLI lifecycle event | Hook | Slash command |
| Pass arguments and have them substituted into the prompt | Slash command with $ARGUMENTS / $1–$9 | Plain skill |
| Bundle a command + its skills + its MCP servers to share | Plugin | Slash command alone |
In Claude Code the line is fuzzy — your user-defined skill is the slash command. Decide by intent: if the model should be able to invoke it on its own, you wrote a skill; if you want it to fire only on your keystroke, set disable-model-invocation: true and treat it as a slash-command-first artefact.
How it works in each tool
Section titled “How it works in each tool”Bundled slash commands ship with Claude Code: /simplify, /batch, /debug, /model, /mcp, /context, /resume, /plan, /clear, and more.
User-defined slash commands are skills. A skill at .claude/skills/<name>/SKILL.md is invokable as /<name>. The legacy .claude/commands/<name>.md form still works but skills are the recommended path.
Plugin slash commands are namespaced: /my-plugin:review.
Argument passing: the $ARGUMENTS placeholder in the skill content is replaced with whatever the user typed after the command.
Invisible-by-default: set disable-model-invocation: true in frontmatter so Claude won’t auto-load the skill — you must type /<name> to use it. Good for skills with side effects.
Built-in slash commands: /model, /review, /approvals, /diff, /mcp, /skills, and others. Codex also lets you queue input (including a slash command) with Tab while a turn is running — it fires once the current turn finishes.
Custom prompts are a distinct primitive: drop a markdown file in ~/.codex/prompts/ and invoke it from the TUI.
Skills are also invokable, via /skills to browse or $<skill-name> to invoke directly. Skills and custom prompts overlap in practice — custom prompts are simpler; skills are more structured. OpenAI now flags custom prompts as deprecated and recommends Skills for reusable prompts.
Argument passing in custom prompts: positional $1–$9 for space-separated tokens, $ARGUMENTS for the full tail, $$ for a literal $. Named placeholders like $FILE or $TICKET_ID are supported. Frontmatter accepts description and argument-hint.
Invocation: custom prompts use /<name> (filename minus .md); skills use $<skill-name> (or pick interactively from /skills). They are not interchangeable syntaxes.
Commands live in .opencode/commands/ (project) or ~/.config/opencode/commands/. Each command is a markdown file with optional frontmatter; invokable as /<name>.
Argument passing: $ARGUMENTS substitutes the full string the user typed after the command; $1, $2, … substitute positional tokens.
Skills (skills/) are a separate primitive — commands are the user-triggered slash surface specifically.
Two distinct surfaces.
Editor (Agent chat). Typing / in chat opens a picker listing subagents (/verifier ...), skills (/skill-name), and custom commands. Custom commands were introduced in Cursor 1.6 and live in .cursor/commands/ as markdown files. Argument passing is limited compared to Claude Code’s $ARGUMENTS pattern; the community has open requests for richer templating. Argument-passing semantics unverified as of 2026-05-21.
CLI (cursor-agent). A fixed set of built-in slash commands:
/plan,/ask— switch modes/model,/max-mode,/auto-run,/sandbox— config/new-chat,/resume,/compress,/logout,/quit— session/mcp list,/mcp enable <name>,/mcp disable <name>— MCP control/rules,/commands— open editors to create or modify rules and custom commands/usage,/about,/help,/feedback— utility
@ mentions are a separate primitive — they attach context (files, folders, symbols, docs, rules, skills). @ adds something to the prompt; / runs something.
Team Commands (Cursor 2.0, Enterprise) push custom commands centrally from the team dashboard — no local file needed.
Chat built-ins (VS Code, JetBrains, web):
/explain— explain selected code or context/fix— propose a fix for errors or selection/tests— generate tests/new— scaffold a new project or file/doc— generate documentation/optimize— suggest performance improvements/help— list available commands/clear— clear chat history/init— generate a starter.github/copilot-instructions.md/create-prompt— generate a reusable prompt file
Prompt files are Copilot’s custom-command primitive: .github/prompts/*.prompt.md. Configurable location via chat.promptFilesLocations. Invoked as /<prompt-name> from chat. Support frontmatter (mode, tools, description) and can reference instructions files. This is the closest analog to Claude Code’s user-defined slash commands.
Chat participants (@-mentions, VS Code): @workspace (renamed/restructured in late-2025 toward agent mode — Unverified as of 2026-05-21 whether @workspace was removed or merged into agent mode), @vscode, @terminal, @github, plus @<extension-name> for any installed Copilot Extension. @ attaches context; / runs an action.
Other surfaces (non-IDE). The copilot CLI has its own slash set (/login, /model, /context, /compact, /experimental, /lsp, /feedback), and gh copilot (the GitHub CLI extension) is a separate tool with subcommands (gh copilot suggest, gh copilot explain) — not Chat slash commands.
Comparison
Section titled “Comparison”| Aspect | Claude Code | Codex | OpenCode | Cursor | Copilot |
|---|---|---|---|---|---|
| User-defined slash commands | Skills (/<name>) | Custom prompts + Skills | commands/ | .cursor/commands/ (1.6+) | .github/prompts/*.prompt.md |
| Bundled commands | Yes (/simplify, /batch, …) | Yes (/model, /review, …) | Yes | Yes (CLI built-ins + chat picker) | Yes (/explain, /fix, /tests, …) |
| Plugin/namespaced | /plugin:cmd | — | No (plugins can’t register slash commands today) | — | Via Copilot Extensions |
| Arguments | $ARGUMENTS | $1–$9, $ARGUMENTS, named ($FILE) | $ARGUMENTS, $1, $2, … | Limited (Unverified) | Prompt-file frontmatter + body |
| Queueable for next turn | No | Yes | No (executes immediately) | — | — |
| Centrally managed for teams | Plugins / managed settings | — | — | Team Commands (Enterprise) | Org-level prompt files (Unverified) |
Name collisions
Section titled “Name collisions”- In Claude Code, slash commands and skills are nearly the same thing — every user-invokable skill is reachable as a slash command. In Codex, OpenCode, Cursor, and Copilot they’re separate primitives that overlap in use.
- “Commands” in OpenCode ≠ “commands” in Claude Code’s old
.claude/commands/(now mostly superseded by skills). - Cursor’s
/(run something) vs@(attach context) is a deliberate split — don’t confuse the two surfaces. - Copilot’s prompt files are the custom-command primitive; “chat participants” (
@workspace,@vscode) are a different surface for scoping context.