CCAF logo

Domain 3 · Task 3.2

Slash Commands & Skills

Create and configure custom slash commands and skills.

Custom slash commands and skills package reusable prompts and procedures behind a /name invocation. The two decisions that matter are scope — project-scoped (shared via VCS) versus user-scoped (personal) — and skill frontmatter, which controls how a skill runs. Recent Claude Code unifies commands into skills, but for the exam, both .claude/commands/ and .claude/skills/ count as valid "project-scoped, version-controlled" answers.

Key concept

Team-shared command → .claude/commands/ (committed). Verbose/exploratory skill → context: fork (runs in an isolated subagent). Restrict damage → allowed-tools. Prompt for a missing parameter → argument-hint.

What you need to know

Command scope: project vs user

A command's location decides who can use it:

  • Project-scoped — .claude/commands/*.md, committed to the repo, so every developer gets it on clone or pull.
  • User-scoped — ~/.claude/commands/*.md, personal to you and never shared.

This mirrors the CLAUDE.md hierarchy: if a /review command must be available to the whole team automatically, it belongs in .claude/commands/ in the repo — not in your personal ~/.claude/commands/, not in CLAUDE.md (which is context, not a command), and not in some config.json commands array (which does not exist).

text
my-repo/.claude/commands/review.md   # PROJECT — every dev gets /review on clone
~/.claude/commands/scratch.md         # USER — personal, not shared

Skills and SKILL.md frontmatter

Skills live in .claude/skills/<name>/SKILL.md (project) or ~/.claude/skills/<name>/SKILL.md (personal), and their frontmatter controls execution:

  • context: fork runs the skill in an isolated subagent so its output does not pollute the main conversation. Use it for verbose work (codebase analysis) or exploratory work (brainstorming) that would otherwise flood context.
  • allowed-tools restricts which tools the skill may use during execution — e.g. limit it to file writes to prevent destructive actions.
  • argument-hint prompts the developer for required parameters when the skill is invoked without arguments.

Personal skill variants go in ~/.claude/skills/ under a *different name* so they do not affect teammates.

yaml
---
name: analyze-codebase
description: Deep-dive a module and summarize its structure
context: fork
allowed-tools: Read, Grep, Glob
argument-hint: <path to the module to analyze>
---
Analyze the module at $ARGUMENTS. Report structure, entry points, and risks.

Skill vs CLAUDE.md: on-demand vs always-loaded

The framing question is *when* the guidance should apply. A skill is on-demand — invoked for a specific task, and its body loads only when used. CLAUDE.md is always-loaded — universal standards read at the start of every session. Put a reusable, task-specific procedure in a skill; put universal conventions everyone always needs in CLAUDE.md. Choosing a skill keeps rarely-needed instructions out of the default context, which is exactly why context: fork pairs so well with heavy, occasional analysis.

Exam traps

The trapThe reality
A /review command belongs in ~/.claude/commands/ so it is ready on your machine.That is personal scope. For every developer to get it on clone/pull, commit it to .claude/commands/ in the repo.
You can register commands in a config.json commands array.No such array exists. Commands are markdown files in .claude/commands/ (or skills in .claude/skills/).
Putting the command's prompt in CLAUDE.md is the same as creating a slash command.CLAUDE.md supplies always-loaded context, not an invocable /name command. Use .claude/commands/ or a skill.
context: fork is only about performance and has no effect on the conversation.It runs the skill in an isolated subagent so verbose/exploratory output never pollutes the main conversation — a context-hygiene tool.

Practice scenario

Real questions from the bank that test this topic — the correct answer is highlighted.

You're writing a custom slash command /test-coverage that should:

  • Be available across all your projects
  • Accept a file path as an argument
  • Restrict the agent to only Read , Bash , and Grep during execution
  • Use a faster model than your default

Which combination of file location and frontmatter is correct?

A~/.claude/commands/test-coverage.md with frontmatter setting allowed-tools , argument-hint , model , descriptionCorrect
B/repo/.claude/commands/test-coverage.md with the same frontmatter
CAn embedded section in ~/.claude/CLAUDE.md defining the command inline
D~/.claude/slash/test-coverage.yaml with YAML config

Why: User-level slash commands live in ~/.claude/commands/ and are available across all projects — matches the requirement. Frontmatter supports allowed-tools (restrict the tool set during execution), argument-hint (UI hint about expected arguments), model (override default), and description (shown in the command list). Project-level (B) would only work in that one repo. CLAUDE.md (C) isn't where slash commands are defined. The path/extension in (D) is invented.

Your team has built a custom skill that helps Claude review SQL queries for performance issues. The skill includes a SKILL.md and several supporting scripts. You want Claude to automatically reach for this skill whenever a user asks "is this query going to be slow?" or "review my SQL."

Which SKILL.md frontmatter element is most critical to get right for automatic discovery?

Aname — it's the identifier Claude uses internally to invoke the skill
Bdescription — Claude reads it to decide whether the skill applies to the current taskCorrect
Cversion — Claude only loads the latest version of a skill
Dtriggers — a list of keywords that activate the skill

Why: Skills are discovered by their description — Claude reads descriptions and decides whether a skill applies to the current task. A vague or generic description means the skill won't trigger when it should; a precise, specific description ensures it does. name (A) is the identifier but doesn't drive discovery. There's no triggers field (D) — the description does that job. Version (C) isn't the discovery gate. The single biggest lever for skill effectiveness is description quality.

Build exercise

Ship a team /review command and an isolated analysis skill

~40 min
  1. 1
    Create .claude/commands/review.md with a reusable code-review prompt template and commit it.

    Why: Project scope makes the command available to every developer automatically.

  2. 2
    Invoke /review in a fresh clone to confirm it is picked up without any per-user setup.

    You should see: The command runs from the committed file — no personal configuration needed.

  3. 3
    Create .claude/skills/analyze-codebase/SKILL.md with context: fork and allowed-tools: Read, Grep, Glob.

    Why: context: fork isolates the verbose analysis; allowed-tools blocks any accidental writes.

  4. 4
    Add an argument-hint and invoke the skill with no argument to see the prompt for the required parameter.

    You should see: Claude Code asks for the module path instead of guessing.

  5. 5
    Run the skill on a large module and confirm the detailed output stays in the subagent rather than filling the main conversation.

    You should see: The main context receives a summary, not the full analysis transcript.

Sources

Drill Claude Code Configuration & Workflows

Practice only this domain’s questions, untimed, with instant explanations.