Custom slash commands — one-keystroke skills shared via repo
Scorecard question: How many custom slash commands do you have in
.claude/commands/or.cursor/skills/invoked as/skill-name? Max-score answer (3 pts): 8+, with some shared with the team via repo.
Why this matters in 2026
Section titled “Why this matters in 2026”Slash commands turn a multi-step prompt into a one-keystroke skill. The team that ships fastest is the team with the most internalized shortcuts. Every time you re-type “review the diff, check for missing tests, flag any secrets, and post a summary in the PR style our team uses” — that’s a slash command waiting to happen. Once it lives at /review, the same five-paragraph instruction collapses to seven characters and runs identically across every engineer. The compounding effect is enormous: a team with 10 well-tuned slash commands ships code review, test scaffolding, migration drafts, and release notes in seconds, while a team without them still pastes the same prompts from a private Notion page. 2026 is the year this gap became visible on velocity dashboards.
The second-order effect matters even more than keystroke savings. Slash commands are executable team conventions. A /pr-description command is a version-controlled, code-reviewed record of how your team writes PR descriptions. A /migration-plan command encodes the checklist senior engineers run through on every schema change. When a new hire joins, they don’t read a wiki page — they type /migration-plan and the senior brain is in the loop. This is why “8+ shared via repo” is the max-score answer — the sharing is the whole point. A private folder helps one person; a committed one lifts the whole team.
What “max score” actually looks like
Section titled “What “max score” actually looks like”A max-score Q7 setup has a .claude/commands/ or .cursor/skills/ directory at the root of the repo (not just in your home directory), checked into git, with at least eight markdown files covering the workflows the team runs most often. The contents are concrete and specific to the codebase, not generic prompts copied from a blog post. A typical layout looks like this:
.claude/commands/├── review.md # Code review with our team's checklist├── pr-description.md # PR description in our template├── migration-plan.md # D1 migration checklist├── test-scaffold.md # Vitest scaffold for new modules├── release-notes.md # Release notes from commit log├── security-scan.md # OWASP-style scan of changes├── docs-update.md # Sync MDX docs to code changes└── i18n-check.md # Confirm PL+EN parity for new copyEach file is a markdown document with a YAML frontmatter block (description, optional allowed-tools, optional argument-hint) and a body that’s the actual prompt — usually 20–80 lines. Engineers invoke them with /review, /pr-description path/to/spec.md, /migration-plan add-user-flags-table. Arguments after the command name flow into $ARGUMENTS (or indexed $1, $2) inside the markdown. The whole directory is committed, so git pull on a clean checkout gives a new hire the same eight keystrokes as the team lead. Some commands are project-scoped (.claude/commands/ in the repo); a few are personal (~/.claude/commands/) for habits that aren’t team standards yet — a 70/30 split is healthy.
Compare that to lower tiers: zero custom commands (0 pts — every prompt re-typed), 1–2 commands kept only in ~/.claude/commands/ (1 pt — feature discovered but not institutionalized), 3–7 commands with one or two shared (2 pts — building the muscle but no team alignment yet). The leap from 2 to 3 pts is sociological more than technical: it’s the moment a team agrees “this is how we review PRs” and commits the prompt to the repo.
Current landscape (web-search-verified)
Section titled “Current landscape (web-search-verified)”The 2026 slash-command ecosystem has standardized on markdown files in a well-known directory, with the three Tier 1 tools converging on subtly different paths and capabilities. Understanding the differences separates a portable library from one that only works in one tool.
Claude Code .claude/commands/ (markdown files, arguments)
Section titled “Claude Code .claude/commands/ (markdown files, arguments)”Claude Code’s slash-command system is the most mature. Two scopes coexist: project commands in .claude/commands/ (committed, shared) and personal commands in ~/.claude/commands/ (your home directory, available everywhere). Both invoke the same way — /command-name at the Claude Code prompt — and both are just markdown files. The file review.md becomes the command /review automatically. Frontmatter is optional but recommended; description is what appears in the / menu picker, and allowed-tools can restrict which tools the command may invoke (useful for read-only commands like a code review).
Arguments are passed via $ARGUMENTS (the full string after the command name) or indexed $1, $2, etc. with shell-style quoting:
---description: Review the current diff against our team checklistallowed-tools: - Read - Bash(git diff:*) - Bash(git log:*)argument-hint: "[scope, e.g. 'security' or 'perf']"---
Run `git diff --stat` and `git diff` to see the current changes. Then review them againstour team checklist:
1. **Types** — Are all function parameters explicitly typed? Any `any` slipping in?2. **Tests** — Does every new function have at least one Vitest test in `tests/unit/`?3. **i18n** — If user-facing copy changed in `/en/`, is the `/pl/` translation updated?4. **Secrets** — Any API keys, tokens, or `.env` values committed accidentally?5. **Migration safety** — Any `ALTER TABLE` or `DROP` without a rollback path?
Focus extra attention on: $ARGUMENTS
Output format: For each issue, give the file path, line range, the problem, and a fix.End with a one-line verdict: SHIP, FIX FIRST, or REWORK.Invoke as /review or /review security. The $ARGUMENTS token expands to whatever the engineer typed after the command name. Note: as of 2026, Anthropic nudges users toward the newer .claude/skills/<name>/SKILL.md format, which supports /skill-name invocation and autonomous invocation by Claude. The CLI still supports both — .claude/commands/ for explicit invocation only, .claude/skills/ for explicit + model-driven. For Q7, either format counts as long as the command is invoked as /skill-name.
Cursor .cursor/skills/
Section titled “Cursor .cursor/skills/”Cursor (with Composer 2.5) reads skills from .cursor/skills/ in the project root. Unlike Claude Code, Cursor has no personal/global skills directory — all skills are project-scoped, which is actually a feature if your goal is shared team setups (it forces you to commit them). Each skill is a folder containing a SKILL.md file:
.cursor/skills/├── code-reviewer/│ └── SKILL.md├── test-generator/│ └── SKILL.md└── migration-planner/ └── SKILL.mdThe SKILL.md uses the same frontmatter + markdown body convention as Claude Code, and Cursor invokes them via the / picker in the Agents panel. Because everything is in the repo, git clone plus a workspace reload gives every teammate the same skills with no extra setup. This is the cleanest “shared via repo” story of the three tools — there’s literally no other place skills can live.
A practical Cursor .cursor/skills/test-generator/SKILL.md for a Vitest project:
---name: test-generatordescription: Generate Vitest tests for the file at $1 following our team conventions---
Generate Vitest unit tests for the file at `$1`.
Our conventions:- Tests live under `tests/unit/` mirroring the source path.- Use `happy-dom` for any DOM access (already configured in `vitest.config.ts`).- Mock Cloudflare bindings using helpers in `tests/utils/mocks.ts`.- Each exported function gets at least one happy-path test and one error-path test.- Use `describe()` blocks per function, `it()` blocks per case.
Read the source file first. Identify each exported function and its signature.Write the tests file at the mirrored path. Run `npm test` and confirm all green.Invoke as /test-generator src/lib/db/queries.ts. Note that Cursor’s argument substitution uses the same $1 / $ARGUMENTS convention as Claude Code, which makes copying a skill between the two tools nearly mechanical.
Codex limitations + workaround via Skills
Section titled “Codex limitations + workaround via Skills”This is the asterisk on Q7 for OpenAI users. Codex CLI does not support user-authored custom slash commands — only built-ins (/init, /skills, etc.) work in the slash menu. There’s an open issue (openai/codex #13893) requesting “Add custom slash commands from SKILL.md”, but as of mid-2026 it isn’t shipped. The closest analog is Skills: Codex reads them from ~/.codex/skills/<name>/SKILL.md (personal) or .codex/skills/<name>/SKILL.md (project-scoped), applied via the /skills picker or referenced in a prompt — but not via a direct /skill-name shortcut.
If you’re a Codex-primary user, score Q7 against your Skills coverage instead: 8+ skills in ~/.codex/skills/ or .codex/skills/ with some committed to the repo is the equivalent max-score answer. The semantic intent of Q7 (do you have a library of reusable, version-controlled workflows?) maps cleanly onto Skills. A Codex SKILL.md looks identical to a Cursor or Claude Code skill — same frontmatter, same markdown body — so a well-designed library is portable across all three tools with minor path tweaks.
---name: pr-descriptiondescription: Draft a PR description in our team template from the commit log---
Run `git log $(git merge-base HEAD main)..HEAD --oneline` to see the commits.Then `git diff $(git merge-base HEAD main)..HEAD --stat` for the file scope.
Write a PR description with these sections:- **Summary** — 1-2 sentences. What changed and why.- **Changes** — bulleted list of the meaningful file changes (skip lockfile/config noise).- **Testing** — How a reviewer can verify this works. Include test command.- **Risk** — Any deploy ordering, migration, or rollback caveats.
Output the markdown only, no commentary.Step-by-step: building your slash-command library
Section titled “Step-by-step: building your slash-command library”- List the prompts you re-type most often this week. Open your shell history, your terminal-agent transcript folder (
~/.claude/projects/), and your notes app. Write down every multi-step instruction you’ve pasted more than twice in the last seven days. A typical engineer finds 12–18 candidates. - Pick the eight that map onto a team workflow. “Generate a Vitest test for this file” — team workflow. “Translate this PR title to a concise version” — personal habit. Eight team-workflow commands is the floor; you’ll usually find 10–12 worth committing.
- Create the directory and the first file. From repo root:
mkdir -p .claude/commands(Claude Code) ormkdir -p .cursor/skills/<name>(Cursor). Createreview.mdorreview/SKILL.mdwith frontmatter and body following the examples above. Keep the first one 20–50 lines. - Add the YAML frontmatter properly.
descriptionmatters most — it’s what appears in the/picker and helps the model decide when a skill is relevant. Make it concrete (“Review the diff against our Vitest + Drizzle + i18n checklist”, not “Reviews code”). For read-only commands, addallowed-tools. - Pass arguments through
$ARGUMENTSor$1. Use$ARGUMENTSfor the full string or$1,$2for indexed positional args. Add anargument-hintin frontmatter so the picker shows what to type. - Commit to the repo and PR it. This turns a personal hack into a team standard. PR the directory with a short README explaining each command. Invite teammates to add their own. The first commit unlocks the “shared via repo” half of the max-score answer.
- Run each command in a real workflow within 48 hours. A slash command you wrote but never used is a dead artifact. Use
/reviewon your next PR. Use/test-generatoron the next new module. - Iterate the markdown after each use. When
/reviewmisses something, add that case to the file. When/pr-descriptionoutput needs reformatting, change the template. After a quarter, your/reviewoutperforms most engineers’ unaided prompts — because every team-specific learning is baked in. - Cross-tool portability check. If your team uses more than one of Claude Code / Cursor / Codex, structure skills so the same
SKILL.mdworks in.claude/skills/<name>/and.cursor/skills/<name>/— they share the format. Use a symlink, a top-levelskills/directory, or a build step. Don’t write three versions. - Onboarding test. Hand a teammate a fresh clone. Within their first hour, they should be able to type
/review,/test-generator,/pr-descriptionand get useful output. If they can’t, the library isn’t actually shared — it’s just committed.
Common pitfalls
Section titled “Common pitfalls”- Over-engineering the first command. Don’t try to write the perfect
/reviewon day one with 200 lines of branching logic. Ship a 30-line first draft, use it ten times, then iterate. The 200-line version after a month of real use is dramatically better than the 200-line version written in a vacuum. - Hidden dependencies on personal setup. A command referencing
~/scripts/my-linter.shor assuming a tool the team doesn’t have isn’t a team command. Before committing, ask: would this work on a fresh teammate’s machine after a clean clone? - Not version-controlling the commands. Keeping
~/.claude/commands/private is fine for personal habits, but every team-shared workflow belongs in the repo. The failure mode is “I’ll keep them locally for now” — six months later, the team has 30 private commands and zero shared ones, scoring 1 pt instead of 3. - Generic commands copied from blog posts. A
review.mdthat says “Review the code carefully” is worse than nothing — it occupies the namespace without adding value. Every command should reflect your codebase’s conventions: your test framework, migration patterns, i18n rules. - Mixing project and personal in the same directory. Personal habits stay in
~/.claude/commands/. Team conventions go in.claude/commands/. If you can’t articulate “every engineer should use this”, it’s a personal command. - Treating slash commands as immutable. A command that hasn’t changed in three months is probably stale. Schedule a quarterly review — drop unused ones, sharpen the heaviest-used ones, add the workflows that have emerged.
- Codex users skipping the question. Don’t score yourself 0 on Q7 just because Codex doesn’t support user-authored slash commands. Score against Skills coverage instead.
How to verify you’re there
Section titled “How to verify you’re there”.claude/commands/or.cursor/skills/(or.codex/skills/) exists at the root of your active repo and is committed to git.- The directory contains 8+ markdown files, each a real workflow your team runs.
- Each file has YAML frontmatter with a concrete
description, and the body uses$ARGUMENTSor$1where appropriate. - Engineers invoke commands like
/review,/pr-descriptionas part of daily work — not just on the day they were written. - New hires get the same commands on
git clonewith no extra setup. - The library has been edited at least once in the last 30 days — a living artifact, not a one-time commit.
- You can name the eight commands and explain when each is used without looking them up.