What you will be able to do
- Write a skill, and predict which one runs when a skill, a command file or a bundled command share a name
- Define a subagent in a file and describe what the built-in Explore, Plan and general-purpose subagents can do
- Tell which slash commands work in non-interactive mode
- Run Claude Code headless with -p, choose an output format and stream events
- Continue or resume sessions from a script and set the permission mode for unattended runs
1.Skills and custom commands
A skill is a reusable prompt stored at <location>/.claude/skills/<skill-name>/SKILL.md. Its description tells Claude when to use it, and you can also run it yourself as /skill-name. The body can include shell output inline. In the example below, !git diff HEAD puts the current diff into the prompt.
---
description: Summarizes uncommitted changes and flags anything risky. Use when the user asks what changed, wants a commit message, or asks to review their diff.
---
## Current changes
!`git diff HEAD`
## Instructions
Summarize the changes above in two or three bullet points, then list any risks you notice such as missing error handling, hardcoded values, or tests that need updating. If the diff is empty, say there are no uncommitted changes.Custom commands came first. They are Markdown files in .claude/commands/, which still work and accept the same frontmatter as skills except name and paths. For new work, prefer skills, because a skill folder can hold supporting files as well as SKILL.md.
| Same name in | Which one runs |
|---|---|
| Two of enterprise, personal and project | Enterprise over personal, personal over project |
| A skill and a file in .claude/commands/ | The skill |
| Your skill and a bundled skill | Your skill replaces the bundled command, but not its aliases |
| A plugin skill and a local skill | Both load, because plugin skills are namespaced as /plugin-name:skill-name |
Sources1
2.Agents: subagents with their own context
A subagent runs a delegated task in a separate context. Subagents keep exploration out of your main conversation, can be limited to certain tools, can use their own focused system prompt, and can run on a cheaper model. Claude Code includes built-in subagents. Explore and Plan get read-only tools, with Write and Edit denied: Explore is for searching and exploring the codebase, and Plan is for research during planning. General-purpose gets every tool available to subagents and handles multi-step work and code changes.
---
name: code-reviewer
description: Reviews code for quality and best practices
tools: Read, Glob, Grep
model: sonnet
---
You are a code reviewer. When invoked, analyze the code and provide
specific, actionable feedback on quality, security, and best practices.| Location | Scope | Priority |
|---|---|---|
| Managed settings | Organization-wide | 1 (highest) |
| --agents CLI flag | Current session | 2 |
| .claude/agents/ | Current project | 3 |
| ~/.claude/agents/ | All your projects | 4 |
| Plugin's agents/ directory | Where plugin is enabled | 5 (lowest) |
Besides description, tools and model, the frontmatter accepts fields such as disallowedTools, permissionMode, hooks, maxTurns, skills, memory, omitClaudeMd and isolation. The sources for this lesson list these fields without explaining how each behaves. After you create the first agent file in a new agents directory, restart the session to load it.
Over several months, Claude has written extensive notes into a project's auto memory, and `MEMORY.md` has grown to 340 lines while individual topic files like `debugging.md` and `api-conventions.md` remain untouched in the same directory. A new session starts in this project. What gets loaded into context automatically at session start?
Correct answer: A — Only the first 200 lines (or 25KB, whichever comes first) of `MEMORY.md`; the topic files load later only if Claude reads them on demand with its file tools.
- A. Correct. The first 200 lines or 25KB of MEMORY.md, whichever comes first, load at session start; content beyond that threshold and topic files load only on demand.
- B. Incorrect. Topic files like debugging.md are not loaded at startup; Claude reads them on demand using standard file tools.
- C. Incorrect. Auto memory is loaded automatically at the start of every session when enabled; running `/memory` is only needed to browse or edit it.
- D. Incorrect. The limit applies to the first 200 lines from the top of the file, not the most recently written lines at the end.
Sources2
3.Built-in and custom slash commands
You type built-in commands and your own skills in the same way. Built-ins include /model, /effort and /config. Bundled skills such as /verify work like skills you write: they hand Claude a prompt. Not every command works in every mode. Custom commands and user-invoked skills work in a non-interactive run if you put them in the prompt string. Commands that exist only in the terminal interface, such as /login, do not.
Pass the value as an argument: /model sonnet, or /config thinking=false. In non-interactive mode, /model, /effort, /fast, /color and /rename take the value as an argument.
Sources3
4.Headless mode with -p
Adding -p runs Claude Code non-interactively. It takes a prompt, can read piped input, and prints its result, so it fits in scripts and CI. With no one to answer permission prompts, you approve tools in advance with --allowedTools. --bare starts a minimal session, and you then add configuration explicitly with flags such as --settings, --mcp-config, --agents or --append-system-prompt.
cat build-error.txt | claude -p 'concisely explain the root cause of this build error' > output.txt| --output-format | What you get |
|---|---|
| text (default) | Plain text output |
| json | Structured JSON with result, session ID and metadata. Add --json-schema to get a structured_output field |
| stream-json | Newline-delimited JSON for real-time streaming |
Sources3
5.Session management and streaming
Every run is a session with an ID. --continue picks up the most recent conversation. --resume takes a specific session ID, which you can read from json output. That makes a multi-step pipeline possible, where each call builds on the previous one.
session_id=$(claude -p "Start a review" --output-format json | jq -r '.session_id')
claude -p "Continue that review" --resume "$session_id"Streaming mode is stream-json output together with --verbose and --include-partial-messages. It emits events as they happen, so a program can show text as it is generated. The stream also includes system events such as api_retry, which carry fields like attempt, retry_delay_ms and session_id.
claude -p "Write a poem" --output-format stream-json --verbose --include-partial-messages | \
jq -rj 'select(.type == "stream_event" and .event.delta.type? == "text_delta") | .event.delta.text'An organization deploys a `Bash(curl *)` deny rule through managed settings so no developer can override it. A project's checked-in `.claude/settings.json` adds an allow rule for `Bash(curl *)` so the CI pipeline can fetch build artifacts. A developer working locally runs `curl` from an interactive session. What happens?
Correct answer: A — The command is still blocked, because managed settings sit at the top of the precedence order and cannot be overridden by project, local, or user settings.
- A. Correct. Managed settings are the highest-priority scope and cannot be overridden by any other scope, so the deny rule still blocks the command regardless of the project's allow rule.
- B. Incorrect. While permission arrays merge across scopes, managed deny rules are not overridable by lower-priority allow rules from project settings.
- C. Incorrect. There is no automatic fallback to a prompt when a managed deny rule exists; the deny simply wins outright.
- D. Incorrect. Precedence is not based on load order; managed settings always outrank project settings regardless of when each file is read.
Sources3
6.Permission modes and auto mode for unattended runs
--allowedTools approves individual tools. --permission-mode sets the behaviour for the whole session: acceptEdits lets file edits through, and auto mode suits longer unattended runs. The sources for this lesson show the flags but do not describe what auto mode allows or blocks internally, so this lesson makes no claims about that.
claude -p "Apply the lint fixes" --permission-mode acceptEdits
claude -p "Update the dependency pins and run the tests" --permission-mode auto --permission-prompts noneSources3
Exam traps
Each one states something that sounds right. Open it to see what is actually true.
1.When a skill exists in both ~/.claude/skills/ and the project's .claude/skills/, the project skill wins because it is more specific.Why is that wrong?
The order is enterprise over personal and personal over project, so the personal skill runs.
Covered in Skills and custom commands
2.The built-in Explore subagent can fix the files it finds.Why is that wrong?
Explore and Plan have read-only tools. Write and Edit are denied, so code changes go to general-purpose.
Covered in Agents: subagents with their own context
3.Every slash command available interactively also works in a -p run.Why is that wrong?
Custom commands and user-invoked skills work, but commands that exist only in the terminal interface, such as /login, are not available.
Covered in Built-in and custom slash commands
Practise it for real
Script a two-step headless review that keeps its session across calls and streams its output.
1.Run: claude -p "Summarize this project" --output-format json | jq -r '.result'
Why: json output gives you the result plus metadata you can parse
You should see: A plain-text summary printed by jq
2.Run: session_id=$(claude -p "Start a review" --output-format json | jq -r '.session_id')
Why: The session ID is how a later call targets this exact conversation
You should see: echo $session_id prints an ID
3.Run: claude -p "Continue that review" --resume "$session_id"
Why: --resume continues a specific session, where --continue takes whichever is most recent
You should see: The reply builds on the first review instead of starting over
4.Run: claude -p "Explain recursion" --output-format stream-json --verbose --include-partial-messages
Why: This shows the event stream a program would read
You should see: Newline-delimited JSON events printed as they arrive
Stuck? Get a nudge
If jq prints null, check that you passed --output-format json. The default text format has no session_id field.
Sources
Every claim above is drawn from one of these pages, quoted as it was written on the date shown.
- 1.https://code.claude.com/docs/en/skillsOfficial docs
“a Markdown file in .claude/commands/ is the older format and still works”
↩︎ Skills and custom commands“Your skill replaces the bundled command, but not its aliases.”
↩︎ Skills and custom commands“With deploy in both ~/.claude/skills/ and the project’s .claude/skills/, /deploy runs the personal one”
↩︎ Exam trap 1 - 2.https://code.claude.com/docs/en/sub-agentsOfficial docs
“Preserve context by keeping exploration and implementation out of your main conversation”
↩︎ Agents: subagents with their own context“read-only tools; Write and Edit are denied”
↩︎ Agents: subagents with their own context“read-only tools; Write and Edit are denied”
↩︎ Exam trap 2 - 3.https://code.claude.com/docs/en/headlessOfficial docs
“User-invoked skills and custom commands work. Include /skill-name in the prompt string and Claude Code expands it before running.”
↩︎ Built-in and custom slash commands“json: structured JSON with result, session ID, and metadata”
↩︎ Headless mode with -p“stream-json: newline-delimited JSON for real-time streaming”
↩︎ Session management and streaming“Continue the most recent conversation”
↩︎ Session management and streaming“claude -p "Update the dependency pins and run the tests" --permission-mode auto --permission-prompts none”
↩︎ Permission modes and auto mode for unattended runs“Built-in commands that only run in the terminal interface, such as /login, aren’t available.”
↩︎ Exam trap 3