Claude Code Skills and Agents: Advanced Techniques
What are Claude Code Skills and Agents?
Skills are markdown-based slash commands that Claude Code executes as instructions — a way to package a repeatable prompt with a fixed format. Agents (subagents) are specialized AI instances that run complex, multi-step tasks in an isolated context and return only the result. Together with Hooks (event-driven automation) and Memory (persistence across sessions), they turn Claude Code from a general-purpose assistant into a tool shaped around a specific project and team.
TL;DR
- -Skills live in .claude/skills/<name>/SKILL.md (new format) or .claude/commands/<skill>.md (legacy, still works); skills take priority on conflict.
- -Frontmatter fields worth knowing: allowed-tools grants tool access without a prompt, model picks haiku/sonnet/opus for that skill, context: fork runs it in an isolated subagent.
- -Agents run in a separate context and return only the final result — the main session never sees intermediate steps, so dozens of files read by a subagent don't clutter it.
- -Hooks now cover 27+ lifecycle events (PreToolUse, PostToolUse, SessionStart, PreCompact, and more); handlers can be a bash command, HTTP endpoint, MCP tool, LLM prompt, or subagent.
- -Memory auto-saves user corrections as feedback_/reference_/project_/user_ files under ~/.claude/projects/<project>/memory/, indexed by MEMORY.md and loaded at session start.
- -Dynamic Workflows — 2026's headline feature — let Claude write and run a JavaScript orchestration script coordinating up to 16 parallel subagents (1,000 max per run) for large-scale audits and migrations.
Claude Code handles 80% of a developer’s day-to-day work out of the box. The remaining 20% is repeatable workflows, project-specific checks, team standards, and automations that a plain prompt can’t capture. Skills, Agents, Hooks, and Memory turn Claude Code from a general-purpose assistant into a tool built around a specific project and team.
This guide covers the full extension system: from writing your first slash command to orchestrating hundreds of parallel subagents through Dynamic Workflows. Every section includes ready-to-copy configurations.
Skills: Slash Commands on Steroids
Skills (slash commands) are markdown files that Claude Code executes as instructions. The user types /review, and Claude receives a detailed prompt with context, constraints, and an output format.
Location and Scope
Skills live in several places. The new format is a <skill-name>/SKILL.md directory; the older .claude/commands/<skill>.md still works, but skills take priority:
| Location | Scope | Label in /help |
|---|---|---|
.claude/skills/<name>/SKILL.md | Current project only | (project) |
~/.claude/skills/<name>/SKILL.md | All of the user’s projects | (user) |
.claude/commands/deploy.md | Current project (legacy) | (project) |
~/.claude/commands/ | All projects (legacy) | (user) |
A .claude/skills/deploy/ directory with SKILL.md inside becomes the /deploy command. Nested directories are supported: apps/web/.claude/skills/deploy/SKILL.md becomes /apps/web:deploy when there’s a name conflict.
File Format
The simplest skill is plain markdown, no frontmatter needed:
Check the current code for SQL injection, XSS, and authentication issues.
Point to specific lines and assign a severity level to each finding.
Save it as .claude/skills/security-scan/SKILL.md and the /security-scan command is ready.
YAML Frontmatter
Frontmatter adds control over the skill’s behavior:
---
description: Review a PR for code quality
allowed-tools: Read, Grep, Bash(git:*)
model: sonnet
argument-hint: [pr-number]
---
Field by field:
description — a short description shown in /help. If omitted, the first paragraph of the content is used instead.
when_to_use — extra context for automatic triggering: trigger phrases, example requests. Appended to the description in listings.
allowed-tools — grants permission for the listed tools without prompting. Bash(git:*) allows git commands without confirmation. Doesn’t restrict other tools — they’re still available but require approval.
disallowed-tools — completely removes tools from what’s available while the skill is active. Resets on the next message.
model — picks a model for the duration of the skill: haiku for quick tasks, sonnet for standard work, opus for complex analysis. A full model ID also works (claude-sonnet-4-6, claude-opus-4-8, claude-haiku-4-5). Defaults to inheriting from the session.
argument-hint — an argument hint shown during autocomplete.
arguments — named positional arguments for $name substitution. For example, arguments: [issue, branch] makes $issue and $branch available.
disable-model-invocation — if true, Claude won’t invoke the skill automatically; only the user can, manually, via /name.
user-invocable — if false, the skill is hidden from the / menu, but Claude can still call it itself. Useful for background instructions.
context: fork — runs the skill in an isolated subagent.
effort — effort level: low, medium, high, xhigh, max. Overrides the session’s effort level for the duration of the skill.
paths — glob patterns: the skill activates automatically only when working with matching files.
license — the skill’s license (name or link). Used when distributing publicly through plugins.
compatibility — environment requirements (OS, Claude Code version, subscription plan).
metadata — extra key-value pairs: owner, version, internal team tags.
Dynamic Arguments
Skills accept arguments via $ARGUMENTS (all arguments as one string) or positionally: $0, $1, $2 (0-indexed).
---
description: Fix an issue by number
argument-hint: [issue-number]
---
Fix issue #$ARGUMENTS following the project's standards.
Read the description, find the relevant code, propose a fix.
Usage: /fix-issue 123 — Claude gets the prompt with the number substituted in.
Positional arguments pass multiple parameters (0-indexed):
---
description: Deploy the application
argument-hint: [environment] [version]
---
Deploy the application to environment $0, version $1.
Check the configuration, run pre-deploy checks, execute the deployment.
Named arguments go through the arguments frontmatter field:
---
description: Deploy the application
arguments: [environment, version]
argument-hint: [environment] [version]
---
Deploy the application to environment $environment, version $version.
Dynamic Context: ! and @
Two mechanisms pull in context at runtime:
@path — includes a file’s contents in the prompt:
Check @tsconfig.json and @package.json for consistency.
Make sure the TypeScript versions match.
!command — runs a bash command and includes its output:
---
allowed-tools: Bash(git:*)
---
Files in the current PR: !`git diff --name-only main...HEAD`
Review each changed file.
Check: code quality, potential bugs, test coverage.
Combining both mechanisms gives context-aware skills:
---
description: Analyze recent changes
allowed-tools: Read Bash(git:*)
---
Last commit: !`git log -1 --format="%H %s"`
Changed files: !`git diff --name-only HEAD~1`
Current branch: !`git branch --show-current`
Analyze the changes in the context of the project.
Check whether they break existing architecture.
Example: A Full /review Skill
---
description: Comprehensive code review with a checklist
allowed-tools: Read Grep Glob Bash(git:*)
model: sonnet
argument-hint: [file-or-directory]
---
## Task
Review the code in $ARGUMENTS (or all changed files if no argument is given).
## Context
Changes: !`git diff --cached --name-only 2>/dev/null || git diff --name-only HEAD~1`
Branch: !`git branch --show-current`
## Checklist
### Pass 1: Correctness
- Logic errors
- Unhandled edge cases
- Null/undefined handling
### Pass 2: Architecture
- Consistency with existing project patterns
- Separation of concerns
- Module coupling and cohesion
### Pass 3: Security
- Input validation
- SQL injection, XSS
- Secret leaks
### Pass 4: Performance
- N+1 queries
- Unnecessary re-renders
- Suboptimal algorithms
## Output Format
For each finding, provide:
- File and line
- Severity: critical / warning / suggestion
- Description of the problem
- Suggested fix
Summary: overall PR verdict (approve / request changes) and key recommendations.
Agents: Autonomous Subagents
Agents (subagents) are specialized AI helpers that perform complex, multi-step tasks in an isolated context. Unlike skills, agents:
- Run in a separate context — they don’t clutter the main session with intermediate results
- Run in parallel
- Have their own system prompts and tool restrictions
- Return only the result, not the full trace of work
- Can run in an isolated git worktree (
isolation: worktree) — the agent gets a clean copy of the repository
Location
| Location | Scope |
|---|---|
.claude/agents/ | Current project only, available to the whole team via git |
~/.claude/agents/ | All of the user’s projects |
File Format
An agent is a markdown file with required frontmatter:
---
name: code-reviewer
description: Use this agent when...
model: inherit
color: blue
tools: ["Read", "Grep", "Glob"]
---
Agent's system prompt...
Frontmatter Fields
name (required) — a unique identifier. Lowercase, digits, hyphens.
description (required) — the most important field. Determines when Claude launches the agent. It’s recommended to include:
- Trigger conditions: “Use this agent when…”
<example>blocks with context, the user’s request, and the assistant’s reaction<commentary>blocks explaining why the agent fits
model (optional, defaults to inherit):
inherit— the current session’s model (recommended)sonnet— balance of quality and speed, resolves toclaude-sonnet-4-6opus— complex analysis, resolves toclaude-opus-4-8haiku— fast tasks, resolves toclaude-haiku-4-5- A full model ID:
claude-opus-4-8,claude-sonnet-4-6,claude-haiku-4-5
color (optional) — a UI color: red, blue, green, yellow, purple, orange, pink, cyan.
tools (optional) — list of available tools. If omitted, the agent inherits all of the session’s tools. Follow the principle of least privilege: an analysis agent shouldn’t have Write.
disallowedTools (optional) — tools explicitly denied to the agent.
isolation (optional) — worktree runs the agent in an isolated git worktree. The worktree is automatically removed if the agent made no changes.
maxTurns (optional) — maximum number of turns the agent can take.
memory (optional) — persistence across sessions: user, project, or local.
effort (optional) — effort level: low, medium, high, xhigh, max.
background (optional) — true runs the agent as a background task.
skills (optional) — a list of skills injected into the agent’s context at launch. Gives the agent expertise without needing to discover skills during execution.
permissionMode (optional) — permission mode: default, acceptEdits, auto, dontAsk, bypassPermissions, or plan.
mcpServers (optional) — a list of MCP servers for the agent: server-name strings or inline {name: config} objects.
hooks (optional) — lifecycle hooks scoped to the agent. All events are supported, but PreToolUse, PostToolUse, and Stop are the most common.
initialPrompt (optional) — an initial prompt the agent receives on launch, before the main task.
Note: for plugin subagents, the
hooks,mcpServers, andpermissionModefields aren’t supported, for security reasons.
Example: Security Scanner Agent
---
name: security-scanner
description: |
Use this agent for security review of code changes.
Triggers on auth, payments, API endpoints, user data handling.
<example>
Context: User modified authentication flow
user: "Review the auth changes I just made"
assistant: "I'll use the security-scanner agent to check for vulnerabilities"
<commentary>Auth changes require specialized security review</commentary>
</example>
<example>
Context: New API endpoint added
user: "Check if this endpoint is secure"
assistant: "I'll use the security-scanner agent to verify input validation and authorization"
<commentary>New endpoints need OWASP Top 10 verification</commentary>
</example>
model: sonnet
color: red
tools: ["Read", "Grep", "Glob", "Bash"]
---
You are a security engineer with an attacker's mindset.
Focus on real-world exploitable vulnerabilities, not theoretical concerns.
## Review Process
1. **Identify attack surface**: endpoints, inputs, auth flows, data access
2. **Check OWASP Top 10**: injection, broken auth, XSS, IDOR, misconfigurations
3. **Verify authorization**: every endpoint checks permissions before data access
4. **Review input validation**: all user inputs validated and sanitized
5. **Check secrets**: no hardcoded API keys, tokens, passwords
## Output Format
For each vulnerability:
- **Location**: file:line
- **Severity**: Critical / High / Medium / Low
- **Category**: OWASP category
- **Description**: what's wrong
- **Exploit scenario**: how an attacker would use this
- **Fix**: specific code change
Summary: total vulnerabilities by severity, overall risk assessment.
Example: Test Writer Agent
---
name: test-writer
description: |
Use this agent to generate comprehensive tests for code.
Triggers on: "write tests", "add tests", "test coverage", new features without tests.
<example>
Context: User implemented a new utility function
user: "Write tests for the parseConfig module"
assistant: "I'll use the test-writer agent to generate comprehensive tests"
<commentary>New code without tests needs systematic test generation</commentary>
</example>
<example>
Context: User asks about test coverage
user: "This module has no tests, fix it"
assistant: "I'll use the test-writer agent to analyze the module and create tests"
<commentary>Missing tests require understanding module contracts</commentary>
</example>
model: inherit
color: green
tools: ["Read", "Write", "Grep", "Glob", "Bash"]
---
You are a testing specialist. Write tests that verify behavior, not implementation.
## Process
1. Read the source code and understand its public API
2. Identify test categories: happy path, edge cases, error handling, integration
3. Check existing test patterns in the project (framework, style, conventions)
4. Generate tests following project conventions
5. Run tests to verify they pass
## Test Design Principles
- **One assertion per test** where practical
- **Descriptive test names**: "should return empty array when input is null"
- **AAA pattern**: Arrange, Act, Assert
- **No implementation coupling**: test behavior through public API
- **Cover edge cases**: null, undefined, empty, boundary values, concurrent access
- **Mock only external dependencies**: database, network, file system
## Output
- Test file(s) following project naming convention
- Summary of coverage: what's tested, what's intentionally skipped and why
Example: Code Reviewer Agent
---
name: code-reviewer
description: |
Use this agent for detailed code review with actionable feedback.
Triggers on: "review this", "check my code", PR review requests.
<example>
Context: User completed a feature implementation
user: "Review the changes in src/api/"
assistant: "I'll use the code-reviewer agent for a detailed multi-pass review"
<commentary>Feature review needs systematic multi-pass analysis</commentary>
</example>
model: sonnet
color: cyan
tools: ["Read", "Grep", "Glob"]
---
You are a senior engineer conducting code review.
Prioritize: Correctness > Security > Performance > Maintainability.
## Multi-Pass Review
### Pass 1: Correctness (mandatory)
- Logic errors, off-by-one, null handling
- All code paths handled
- Error propagation correct
### Pass 2: Architecture
- Fits existing project patterns
- Single responsibility maintained
- No unnecessary coupling
### Pass 3: Performance
- No N+1 queries
- Efficient algorithms for data size
- No memory leaks or unnecessary allocations
### Pass 4: Maintainability
- Code is self-documenting
- No magic numbers or strings
- Tests present and meaningful
## Output Format
**Verdict**: APPROVE / REQUEST CHANGES / NEEDS DISCUSSION
For each finding:
- 📍 Location: `file:line`
- 🔴/🟡/🟢 Severity
- Description and suggested fix
**Summary**: key strengths and areas for improvement.
Isolation and Context
Agents run in an isolated context:
- The main agent doesn’t see the subagent’s intermediate steps — only the final result
- The subagent has no access to the main chat’s history
- Multiple subagents can run in parallel without conflicts
The practical value is in context management: a subagent reads dozens of files and returns only a 20-line summary, keeping the main session clean.
Automatic and Explicit Invocation
Claude Code decides when to launch an agent based on the description. The more precise the examples in <example> blocks, the more accurate the triggering.
Explicit invocation: “Use the security-scanner agent to check this file” — Claude will find the agent by name.
Hooks: Event-Driven Automation
Hooks are handlers that run automatically in response to Claude Code events. They intercept tools, user messages, and session start/end. A handler can be a bash command (command), an HTTP endpoint (http), an MCP tool (mcp_tool), an LLM prompt (prompt), or a subagent (agent).
Core Event Types
As of mid-2026, Claude Code supports 27+ hook events. Here’s the full current table:
| Event | When it fires | Typical use |
|---|---|---|
| PreToolUse | Before any tool call | Validation, blocking, modification |
| PostToolUse | After a tool completes | Formatting, logging |
| PostToolUseFailure | A tool failed | Error handling, retry logic |
| PostToolBatch | After a group of parallel tools completes | Aggregating batch results |
| UserPromptSubmit | The user sent a message | Adding context, validation |
| UserPromptExpansion | The prompt is expanding (via @ or !) | Modifying context before execution |
| Stop | The main agent is about to stop | Checking completeness |
| StopFailure | The agent stopped with an error | Handling abnormal stops |
| SubagentStop | A subagent is about to stop | Checking result quality |
| SubagentStart | A subagent is launching | Initializing the agent’s context |
| TeammateIdle | A team member (Agent Teams) finished a task | Coordination in Agent Teams |
| TaskCreated | A Dynamic Workflows task was created | Tracking workflow tasks |
| TaskCompleted | A Dynamic Workflows task completed | Aggregating workflow results |
| SessionStart | Claude Code session starts | Loading context, setting up the environment |
| Setup | After SessionStart, before the first message | Initializing tools and config |
| SessionEnd | Session ends | Cleanup, logging |
| InstructionsLoaded | CLAUDE.md files are loaded | Auditing loaded instructions |
| ConfigChange | Configuration changes within the session | Reacting to settings changes |
| CwdChanged | The working directory changed (/cd) | Reconfiguring project context |
| PreCompact | Before context compaction | Preserving critical information |
| PostCompact | After context compaction | Restoring state |
| PermissionRequest | Claude requests permission | Custom decision logic |
| PermissionDenied | Permission was denied | Logging, alternative actions |
| Notification | Claude sends a notification | Reacting to events |
| MessageDisplay | An assistant message is displayed | Editing displayed text (doesn’t affect the transcript) |
| FileChanged | A watched file changed | Auto-reloading configuration |
| WorktreeCreate | A git worktree is created | Setting up an isolated environment |
| WorktreeRemove | A git worktree is removed | Cleaning up resources |
| Elicitation | Claude requests input from the user | Intercepting and programmatically handling requests |
| ElicitationResult | The user responded to a request | Post-processing the response |
Note:
WorktreeCreatedoesn’t support a matcher and fires on every event. Any nonzero exit code blocks worktree creation — it’s a blocking event.
Configuration
Hooks are configured in settings.json (user or project scope):
{
"hooks": {
"PreToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "bash /path/to/validate.sh",
"timeout": 10
}
]
}
]
}
}
matcher — which tools to intercept:
"Write"— exact match"Read|Write|Edit"— multiple tools"*"— all tools"mcp__.*"— all MCP tools (regex)
type — the handler type: "command" (bash), "http" (HTTP POST, available since February 2026), "mcp_tool" (an MCP tool), "prompt" (a one-shot LLM evaluation), "agent" (a subagent with tool access for complex verification).
timeout — execution limit in seconds. Default: 60.
Exit Codes
0— success; stdout is parsed as JSON output (fields likesystemMessage,decision,hookSpecificOutput, etc.). For most events, stdout is written to the debug log; Claude only sees it forUserPromptSubmit,UserPromptExpansion,SessionStart.2— blocking error: stdout is ignored, stderr is passed to Claude as an error message. Blocks the action forPreToolUse,UserPromptSubmit,PermissionRequest,Stop,SubagentStop,PreCompact,TaskCreated,TaskCompleted, and others. ForWorktreeCreate, any nonzero code blocks worktree creation.- Any other code (
1,3, etc.) — a non-blocking error; a<hook name> hook errornotification with the first line of stderr, execution continues.
Hook Input
All hooks receive JSON via stdin with common fields:
{
"session_id": "abc123",
"cwd": "/project/path",
"hook_event_name": "PreToolUse",
"tool_name": "Write",
"tool_input": { "file_path": "/path/to/file" }
}
Event-specific fields: tool_name and tool_input for PreToolUse/PostToolUse, user_prompt for UserPromptSubmit, reason for Stop/SubagentStop.
Environment Variables
Available in command hooks:
$CLAUDE_PROJECT_DIR— project root$CLAUDE_ENV_FILE— (SessionStart only) file for persisting environment variables$CLAUDE_EFFORT— the current effort level:low,medium,high,xhigh,max
Example 1: Protecting Critical Files
A hook that prevents Claude from modifying specific files:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "bash ~/.claude/hooks/protect-files.sh",
"timeout": 5
}
]
}
]
}
}
The protect-files.sh script:
#!/bin/bash
set -euo pipefail
input=$(cat)
file_path=$(echo "$input" | jq -r '.tool_input.file_path')
# Protected patterns
PROTECTED=(
".env"
".env.local"
"credentials"
"secrets"
"*.key"
"*.pem"
)
for pattern in "${PROTECTED[@]}"; do
if [[ "$file_path" == *"$pattern"* ]]; then
echo "{\"decision\": \"deny\", \"reason\": \"Protected file: $file_path\"}" >&2
exit 2
fi
done
# Block path traversal
if [[ "$file_path" == *".."* ]]; then
echo "{\"decision\": \"deny\", \"reason\": \"Path traversal detected\"}" >&2
exit 2
fi
exit 0
Example 2: Auto-Format After Write
Automatically format a file after every write:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "bash ~/.claude/hooks/auto-format.sh",
"timeout": 15
}
]
}
]
}
}
The auto-format.sh script:
#!/bin/bash
set -euo pipefail
input=$(cat)
file_path=$(echo "$input" | jq -r '.tool_input.file_path')
# Determine format by extension
case "$file_path" in
*.ts|*.tsx|*.js|*.jsx)
npx prettier --write "$file_path" 2>/dev/null
;;
*.py)
ruff format "$file_path" 2>/dev/null
;;
*.rs)
rustfmt "$file_path" 2>/dev/null
;;
*.go)
gofmt -w "$file_path" 2>/dev/null
;;
esac
exit 0
Example 3: Loading Context at Session Start
A SessionStart hook that loads project context and sets environment variables:
{
"hooks": {
"SessionStart": [
{
"hooks": [
{
"type": "command",
"command": "bash ~/.claude/hooks/load-context.sh",
"timeout": 10
}
]
}
]
}
}
The load-context.sh script:
#!/bin/bash
set -euo pipefail
# Determine project type
if [ -f "package.json" ]; then
echo "export PROJECT_TYPE=nodejs" >> "$CLAUDE_ENV_FILE"
elif [ -f "pubspec.yaml" ]; then
echo "export PROJECT_TYPE=flutter" >> "$CLAUDE_ENV_FILE"
elif [ -f "pyproject.toml" ]; then
echo "export PROJECT_TYPE=python" >> "$CLAUDE_ENV_FILE"
elif [ -f "Cargo.toml" ]; then
echo "export PROJECT_TYPE=rust" >> "$CLAUDE_ENV_FILE"
fi
# Check for uncommitted changes
DIRTY=$(git status --porcelain 2>/dev/null | wc -l | tr -d ' ')
if [ "$DIRTY" -gt 0 ]; then
echo "export GIT_DIRTY=true" >> "$CLAUDE_ENV_FILE"
echo "export GIT_DIRTY_COUNT=$DIRTY" >> "$CLAUDE_ENV_FILE"
fi
# Current branch
BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown")
echo "export GIT_BRANCH=$BRANCH" >> "$CLAUDE_ENV_FILE"
Example 4: Checking Completion (Stop Hook)
A hook that checks whether Claude fully completed the task:
{
"hooks": {
"Stop": [
{
"matcher": "*",
"hooks": [
{
"type": "command",
"command": "bash ~/.claude/hooks/check-completion.sh"
}
]
}
]
}
}
#!/bin/bash
# check-completion.sh
input=$(cat)
# Check whether tests ran, whether the project builds
# Return a nonzero code if needed
exit 0
Parallel Execution
All matching hooks for a given event run in parallel:
- Hooks don’t see each other’s results
- Execution order isn’t deterministic
- Each hook must be independent
Reloading Hooks
Hooks load at session start. Changes to settings.json require restarting Claude Code. Check loaded hooks with the /hooks command.
Note: skill files (SKILL.md) are picked up without a restart — Claude Code watches those directories in real time.
Memory: Persistence Across Sessions
Memory is the mechanism for persisting knowledge across sessions. Claude remembers decisions, patterns, and project context, and doesn’t ask the same thing twice.
Types of Memory
CLAUDE.md files — instructions Claude loads at startup:
| File | Location | Scope |
|---|---|---|
CLAUDE.md | Project root | Project instructions, available to the team |
.claude/CLAUDE.md | Inside .claude | Alternative location |
CLAUDE.local.md | Project root | Personal, gitignored |
~/.claude/CLAUDE.md | Home directory | Global, personal |
Auto-memory — Claude automatically saves feedback and decisions.
Location: ~/.claude/projects/<project>/memory/ (the path is derived from the project’s git repository)
When Claude receives a correction from the user, it saves it to memory files. The MEMORY.md file serves as an index. At session start, the first 200 lines or first 25KB of this file are loaded.
MEMORY.md Structure
# Memory Index
- [feedback_article_tone.md](feedback_article_tone.md) — Article tone: professional, technical
- [feedback_publish_date.md](feedback_publish_date.md) — Publish date = actual publication day
- [reference_telegram_channel.md](reference_telegram_channel.md) — Telegram channel: @futcraft
- [project_reddit_strategy.md](project_reddit_strategy.md) — Reddit Growth Strategy: 6-month roadmap
Types of Memory Files
File names follow a naming convention by type:
feedback_ — corrections from the user. “Don’t add emoji to commits,” “Use vitest, not jest.” The most common type.
reference_ — reference information. Channel IDs, API URLs, key configs. Things Claude won’t find in the code.
project_ — project decisions. Architectural choices, strategies, roadmaps. Context Claude factors into its work.
user_ — personal preferences. Code style, preferred tools, output formats.
Practice: Working With Memory Effectively
Memory works automatically, but you can manage the process explicitly:
-
Correction — correct Claude: “No, use pnpm, not npm.” It’ll save this as feedback and apply it in the next session.
-
Explicit saving — “Remember: in this project, all API responses are wrapped in
{ data, error, meta }.” Claude will create a memory file. -
Review — open
~/.claude/projects/*/memory/MEMORY.md, delete stale entries. -
Migration — if a rule is global, move it to
~/.claude/CLAUDE.md.
CLAUDE.md: Advanced Configuration
CLAUDE.md is the primary mechanism for instructing Claude Code. The file loads at session start and defines Claude’s behavior in the project.
Priority Hierarchy
CLAUDE.md files exist at four levels (from highest to lowest priority):
| Level | Location | Who uses it |
|---|---|---|
| Managed policy | macOS: /Library/Application Support/ClaudeCode/CLAUDE.mdLinux: /etc/claude-code/CLAUDE.md | Org IT/DevOps. Cannot be overridden. |
| Project | ./CLAUDE.md or ./.claude/CLAUDE.md | The team, via git |
| User | ~/.claude/CLAUDE.md | Personal settings for all projects |
| Local | ./CLAUDE.local.md | Personal, for a specific project, gitignored |
An important detail: files are concatenated, not overridden. When instructions conflict, Claude favors the more specific context.
.claude/rules/ With Glob Patterns
The .claude/rules/ directory holds rules that apply to specific files:
.claude/rules/
├── api-endpoints.md # Rules for API files
├── database.md # Rules for migrations and schemas
└── tests.md # Rules for tests
Rules without a paths frontmatter field load at startup. Rules with paths load only when Claude works with matching files:
---
paths:
- "src/api/**/*.ts"
---
# API Development Rules
- All API endpoints must include input validation
- Use the standard error response format
Importing via @path
CLAUDE.md supports importing other files:
@shared-rules.md
@RTK.md
Claude loads the referenced files’ content and includes it in the instructions. Convenient for splitting rules by topic and reusing configurations across projects.
Best Practices for CLAUDE.md
Structure for a project CLAUDE.md:
# Project Name
## Overview
Short project description: stack, architecture, key dependencies.
## Commands
Core commands for development, testing, deployment.
## Architecture
Key architectural decisions Claude should factor in.
## Conventions
Code style, naming, patterns, anti-patterns.
## Known Issues
Current limitations, workarounds, tech debt.
Principles:
- Be specific — “Use pnpm, not npm” instead of “Use the correct package manager.”
- Prioritize — Mark critical rules:
(CRITICAL). - Stay current — Remove stale instructions. 20 up-to-date rules beat 100 stale ones.
- Give context — Explain the reason: “Use edge functions instead of API routes because the project runs on Cloudflare Pages” — Claude understands the constraints better.
- Show examples — Demonstrate the correct format with code examples, not abstract descriptions.
Combinations: Orchestrating the Components
The real power is in combining all the components. Skills launch agents, hooks pass context through env variables, memory accumulates rules across sessions, and Dynamic Workflows scales this to hundreds of parallel tasks.
A Skill Calls an Agent
A skill can include an instruction to launch a specific agent:
---
description: Full PR review cycle
argument-hint: [pr-number]
allowed-tools: Bash(gh:*), Read
---
PR #$ARGUMENTS:
Info: !`gh pr view $ARGUMENTS --json title,body,files`
Phase 1: Run the code-reviewer agent to analyze the changes.
Phase 2: Run the security-scanner agent to check for security issues.
Phase 3: Based on both agents' results, form a final verdict.
Claude launches both agents (potentially in parallel), collects their results, and forms an overall conclusion.
A Hook Informs Claude Through Context
A SessionStart hook loads information that a skill or agent then uses:
# load-context.sh
#!/bin/bash
# Check for open PRs
OPEN_PRS=$(gh pr list --json number,title --limit 5 2>/dev/null || echo "[]")
echo "export OPEN_PRS='$OPEN_PRS'" >> "$CLAUDE_ENV_FILE"
# Last failed CI run
FAILED_RUN=$(gh run list --status failure --limit 1 --json databaseId,name 2>/dev/null || echo "[]")
echo "export FAILED_CI='$FAILED_RUN'" >> "$CLAUDE_ENV_FILE"
Now a skill uses this context:
---
description: Morning project status
---
Show the morning status:
1. Current branch and uncommitted changes
2. Open PRs (from env OPEN_PRS)
3. Last failed CI run (from env FAILED_CI)
4. Priority tasks for today
Memory Informs an Agent
When Claude gets a correction (“Don’t use Lodash in this project, everything’s covered by the standard library”), it’s saved to memory. In the next session, the code-reviewer agent factors this rule in without being reminded — CLAUDE.md and memory load at startup.
The chain: the user corrects Claude → memory saves the feedback → CLAUDE.md loads it at startup → the agent applies it during analysis.
Real Workflows
Workflow 1: Onboarding a New Developer
A new developer clones the project. CLAUDE.md describes the architecture, conventions, and commands. Skills handle the routine:
/setup— installs dependencies, configures the environment, checks prerequisites/architecture— explains the project structure, key modules, data flows/find-examples— finds usage examples of a pattern in the codebase
Agents help with onboarding:
- The
code-revieweragent reviews the first PRs - The
test-writeragent generates tests following project conventions
Hooks enforce quality:
- A PreToolUse hook checks that new code doesn’t break conventions
- A Stop hook checks that tests were written and pass
Workflow 2: Automated PR Review
---
description: Automated PR review
argument-hint: [pr-number]
allowed-tools: Bash(gh:*), Read, Grep, Glob
model: sonnet
---
## PR Review Pipeline
PR: !`gh pr view $ARGUMENTS --json title,body,additions,deletions,changedFiles`
Files: !`gh pr diff $ARGUMENTS --name-only`
### Step 1: Scope Assessment
Assess the scope of the changes. If > 500 lines, warn about large-PR risks.
### Step 2: Code Review
Run the code-reviewer agent on the changed files.
### Step 3: Security Check
If the changes touch auth, API endpoints, or data handling —
run the security-scanner agent.
### Step 4: Test Coverage
Check for tests covering the new functionality.
If there are none, run the test-writer agent.
### Step 5: Final Verdict
Combine the results of all checks.
Format: APPROVE / REQUEST CHANGES with concrete action items.
Workflow 3: Release Management
---
description: Prepare a release
argument-hint: [version]
allowed-tools: Bash(git:*, npm:*, gh:*), Read, Write, Edit
---
## Release Checklist for version $ARGUMENTS
### Pre-release
1. Check: !`git status --porcelain`
2. Current branch: !`git branch --show-current`
3. All tests pass: !`npm test 2>&1 | tail -5`
### Changelog
4. Collect commits since the last release: !`git log $(git describe --tags --abbrev=0)..HEAD --oneline`
5. Generate a changelog in Keep a Changelog format
### Version Bump
6. Update the version in package.json to $ARGUMENTS
7. Update CHANGELOG.md
### Release
8. Create a commit: "chore: release v$ARGUMENTS"
9. Create a tag: v$ARGUMENTS
10. Show the push commands (but don't run them without confirmation)
Workflow 4: Debugging Methodology
---
description: Systematic debugging of an issue
argument-hint: [description]
allowed-tools: Read, Grep, Glob, Bash(*)
model: opus
---
## Systematic Debugging: $ARGUMENTS
### Phase 1: Reproduce
Determine the exact steps to reproduce the problem.
Find the minimal test case.
### Phase 2: Isolate
Use binary search across commits if the issue is a regression.
Determine which module, function, line causes the problem.
### Phase 3: Hypothesize
Formulate 3 hypotheses about the cause.
For each, describe how to verify it and what to look for.
### Phase 4: Verify
Check each hypothesis, starting with the most likely.
Show evidence (logs, values, stack traces).
### Phase 5: Fix
Propose a minimal fix.
Explain why it addresses the root cause, not just the symptom.
Suggest a test that will prevent a regression.
Dynamic Workflows: Orchestrating Hundreds of Subagents
Dynamic Workflows is 2026’s headline update. These are JavaScript scripts that Claude writes itself and runs in the background, coordinating dozens or hundreds of parallel subagents within a single session.
How It Works
You describe the task: “Run a security audit of the entire codebase” or “Migrate from REST to GraphQL.” Claude:
- Builds a plan — decomposes the work into parallel subtasks
- Generates a JavaScript orchestration script
- Launches subagents — up to 16 in parallel, no more than 1,000 total per run
- Validates results before the final answer
Your main session stays responsive: the workflow runs in the background, progress is visible in the UI.
Typical Scenarios
- Codebase audits (security, quality, documentation)
- Large migrations (framework version, API changes)
- Cross-project research spanning multiple sources
Saving and Reusing
Scripts are saved through the workflow menu (press s). Two storage paths:
~/.claude/workflows/— personal- Inside a skill’s folder, referenced in
SKILL.md— for distribution via plugins
---
description: Security audit workflow
---
Run the dynamic workflow from @security-audit.js to audit the entire codebase.
Use the script as a template and adapt it to the current stack.
Availability
Dynamic Workflows are on by default for Max, Team, Enterprise plans and when working through the API. Pro plan users can enable it in /config. Activate via /workflows or the ultracode setting.
Agent Teams: Parallel Team Work
Agent Teams is an experimental feature, disabled by default. Enable it via the
CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMSvariable insettings.json. Has known limitations around session resumption and task management.
Agent Teams extends the subagent model further: multiple Claude instances work in parallel on different subtasks, coordinating through a shared task list.
Unlike manually running several sessions, Agent Teams provides built-in coordination:
- Agents claim tasks without conflicts — through file locking when claiming tasks
- Team members communicate directly via mailbox, not just through a lead agent
- A lead agent coordinates the task list and synthesizes results
The TeammateIdle hook event lets you react when a team member finishes a task — for example, to launch the next processing stage.
Plugins: Distributing Skills and Agents
As the Claude Code ecosystem grew in 2026, a distinction emerged between skills and plugins:
- Skill — a single
SKILL.mdfile with instructions - Plugin — a bundle: several skills + MCP servers + agents + configs, packaged as one installable unit
Plugins are installed via the /plugin command inside Claude Code:
/plugin marketplace add <user-or-org/repo-name>
There’s no centralized official marketplace — the ecosystem is decentralized. Plugins are published in git repositories; a marketplace is connected via a URL or a GitHub repo containing a .claude-plugin/marketplace.json file. Anthropic’s official catalog is available via /plugin marketplace add anthropics/claude-code.
To publish your own plugin, use the license, compatibility, and metadata fields in SKILL.md.
Headless Mode and Automation
Claude Code supports non-interactive execution via the -p flag:
# Basic headless run
claude -p "Run a security audit of src/" --output-format json
# With a turn limit and a specific model
claude -p "Update dependencies to the latest versions" \
--max-turns 30 \
--model claude-opus-4-8 \
--allowedTools "Read,Write,Bash"
# Continuing a previous session
claude --continue -p "Now write tests for the fixed code"
# Structured output
claude -p "Analyze the API and return a JSON report" \
--output-format json \
--json-schema report-schema.json
As of February 2026, a Remote Control mode is available: launch it via /remote-control — Claude shows a QR code to connect from your phone through the Claude app. This gives full session control, including file management and progress monitoring.
The Redesigned Desktop App
In April 2026, Anthropic shipped a major redesign of Claude Code Desktop:
Multi-session support — a sidebar manages all active and recent sessions. Run work across several repositories at once and switch between them as results come in.
Integrated tools — a built-in terminal, file editor, a faster diff viewer for large changesets, HTML/PDF preview, and local server launching.
Custom layout — every panel (terminal, preview, diff, chat) is draggable, and the grid adjusts to your working style.
CLI parity — plugin support and SSH for remote machines (macOS and Linux).
The app is available on all plans: Pro, Max, Team, Enterprise, and via API.
Ready-Made Templates
5 Skills to Copy
1. /adr — Architecture Decision Record
---
description: Create an Architecture Decision Record
argument-hint: [title]
allowed-tools: Read, Write, Glob
---
Create an ADR (Architecture Decision Record) on the topic: $ARGUMENTS
Find existing ADRs: !`ls docs/decisions/ 2>/dev/null || echo "No ADRs"`
ADR format:
# ADR-[NEXT_NUMBER]: $ARGUMENTS
## Status
Proposed
## Context
[What problem is being solved]
## Decision
[What was decided]
## Consequences
### Positive
- [Pros]
### Negative
- [Cons]
### Neutral
- [Neutral consequences]
## Alternatives Considered
[What alternatives were considered and why they were rejected]
Save to docs/decisions/adr-[NUMBER]-[slug].md
2. /test — Run and Analyze Tests
---
description: Run tests and analyze the result
argument-hint: [test-path]
allowed-tools: Bash(npm:*, npx:*, pnpm:*), Read
model: sonnet
---
Run tests: !`npm test -- $ARGUMENTS 2>&1 | tail -50`
If tests passed: a short report, coverage.
If tests failed:
1. Determine the root cause of each failure
2. Propose a specific fix
3. State whether it's a regression or a new bug
3. /deploy — Pre-Deploy Checks
---
description: Pre-deploy checks and deployment
argument-hint: [environment]
allowed-tools: Bash(*), Read
---
## Pre-Deploy Checklist for $ARGUMENTS
1. Git status: !`git status --porcelain`
2. Current branch: !`git branch --show-current`
3. Unpushed commits: !`git log @{u}..HEAD --oneline 2>/dev/null || echo "No upstream"`
4. Tests: !`npm test 2>&1 | tail -10`
5. Build: !`npm run build 2>&1 | tail -10`
If all checks pass, show the deploy command for $ARGUMENTS.
If not, show what needs fixing.
4. /refactor — Safe Refactoring
---
description: Refactor while preserving behavior
argument-hint: [file-or-module]
allowed-tools: Read, Write, Edit, Grep, Glob, Bash(npm:*)
model: opus
---
## Refactoring: $ARGUMENTS
### Phase 1: Understand
Read the code. Determine: what it does, how it's used, which tests cover it.
### Phase 2: Identify
Find code smells:
- Duplication
- Functions that are too long (> 50 lines)
- Deep nesting (> 3 levels)
- Single Responsibility violations
### Phase 3: Plan
Propose a refactoring plan. Each step should:
- Preserve behavior (tests keep passing)
- Be atomic (one commit)
### Phase 4: Execute
Perform the refactoring step by step.
After each step: run the tests.
5. /api-docs — Generate API Documentation
---
description: Generate documentation for an API endpoint
argument-hint: [file-path]
allowed-tools: Read, Grep, Glob
---
Read @$1 and generate API documentation.
Format for each endpoint:
### [METHOD] /path
**Description:** Short description
**Authentication:** Required/Optional
**Request:**
- Headers: ...
- Body: schema with types
**Response:**
- 200: Success schema
- 400: Validation error
- 401: Unauthorized
- 500: Server error
**Example:**
```bash
curl -X POST /api/endpoint \
-H "Authorization: Bearer token" \
-d '{"key": "value"}'
Use types from the code, don’t invent them.
### 3 Agents to Copy
#### 1. Database Migration Reviewer
```markdown
---
name: migration-reviewer
description: |
Use this agent to review database migrations for safety and correctness.
Triggers on: migration files, schema changes, SQL modifications.
<example>
Context: User created a new migration
user: "Review this migration before I apply it"
assistant: "I'll use the migration-reviewer agent to check for data safety issues"
<commentary>Migrations need careful review for data loss, locking, and rollback</commentary>
</example>
model: sonnet
color: yellow
tools: ["Read", "Grep", "Glob"]
---
You are a database migration specialist. Review migrations for safety, correctness, and performance.
## Checklist
1. **Data Safety**
- Can this migration cause data loss?
- Is there a rollback path?
- Are default values set for new NOT NULL columns?
2. **Locking**
- Will this lock tables for a long time?
- Use CONCURRENTLY for indexes on large tables?
- Avoid ALTER TABLE on hot tables during peak hours
3. **Performance**
- Will this migration be fast enough for production data volume?
- Are new indexes necessary and efficient?
- No missing indexes for new foreign keys
4. **Compatibility**
- Is this backward-compatible with current application code?
- Can old and new code run simultaneously during deploy?
## Output
- SAFE / NEEDS ATTENTION / DANGEROUS
- Specific issues with fixes
- Estimated execution time for production data
2. Dependency Auditor
---
name: dependency-auditor
description: |
Use this agent to audit project dependencies for security and health.
Triggers on: "audit dependencies", "check packages", dependency updates.
<example>
Context: User wants to check dependency health
user: "Audit our dependencies"
assistant: "I'll use the dependency-auditor agent to check for vulnerabilities and outdated packages"
<commentary>Regular dependency audits catch vulnerabilities early</commentary>
</example>
model: sonnet
color: yellow
tools: ["Read", "Bash", "Grep"]
---
You are a dependency security specialist. Audit project dependencies comprehensively.
## Process
1. Run security audit: `npm audit` / `pip audit` / `cargo audit`
2. Check for outdated packages with major version gaps
3. Identify packages with known CVEs
4. Check license compatibility
5. Identify abandoned packages (no updates > 2 years)
## Output
### Critical (act now)
- Packages with known exploited vulnerabilities
### High (act this sprint)
- Packages with high-severity CVEs
- Packages 2+ major versions behind
### Medium (plan for)
- Outdated packages with breaking changes ahead
- Packages approaching end-of-life
### Info
- License summary
- Dependency tree depth
- Total package count
3. Performance Profiler
---
name: performance-profiler
description: |
Use this agent to analyze code for performance issues.
Triggers on: "performance", "slow", "optimize", "profiling".
<example>
Context: User reports slow API endpoint
user: "This endpoint takes 3 seconds, find out why"
assistant: "I'll use the performance-profiler agent to analyze bottlenecks"
<commentary>Performance issues need systematic profiling, not guessing</commentary>
</example>
model: opus
color: purple
tools: ["Read", "Grep", "Glob", "Bash"]
---
You are a performance engineer. Find and fix bottlenecks systematically.
## Analysis Process
1. **Identify hot path**: trace the execution path of the slow operation
2. **Database queries**: find N+1, missing indexes, full table scans
3. **Algorithm complexity**: check for O(n^2) or worse in loops
4. **I/O operations**: unnecessary disk reads, synchronous network calls
5. **Memory**: large allocations, data structure inefficiency
6. **Caching**: missed caching opportunities, cache invalidation issues
## Report Format
### Bottleneck #N
- **Location**: file:line
- **Impact**: estimated time/memory cost
- **Root cause**: why it's slow
- **Fix**: specific code change
- **Expected improvement**: quantified estimate
### Summary
- Top 3 bottlenecks ranked by impact
- Quick wins vs. architectural changes
- Recommended order of fixes
2 Hooks to Copy
1. Commit Message Validator (PreToolUse)
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "bash ~/.claude/hooks/validate-commit.sh",
"timeout": 5
}
]
}
]
}
}
#!/bin/bash
# validate-commit.sh
set -euo pipefail
input=$(cat)
command=$(echo "$input" | jq -r '.tool_input.command // empty')
# Only check git commit
if [[ "$command" != *"git commit"* ]]; then
exit 0
fi
# Check for Conventional Commits format
if echo "$command" | grep -q 'git commit.*-m'; then
msg=$(echo "$command" | sed 's/.*-m ["\x27]//' | sed 's/["\x27].*//')
# Conventional Commits pattern
if ! echo "$msg" | grep -qE '^(feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert)(\(.+\))?: .+'; then
echo '{"systemMessage": "Commit message does not follow Conventional Commits format. Use: type(scope): description. Types: feat, fix, docs, style, refactor, perf, test, build, ci, chore, revert."}' >&2
exit 2
fi
fi
exit 0
2. Sensitive Data Guard (PreToolUse)
{
"hooks": {
"PreToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "bash ~/.claude/hooks/sensitive-data-guard.sh",
"timeout": 5
}
]
}
]
}
}
#!/bin/bash
# sensitive-data-guard.sh
set -euo pipefail
input=$(cat)
file_path=$(echo "$input" | jq -r '.tool_input.file_path // empty')
content=$(echo "$input" | jq -r '.tool_input.content // .tool_input.new_string // empty')
# Check the path
BLOCKED_PATHS=(".env" ".env.local" ".env.production" "credentials" "secrets" ".key" ".pem" ".p12")
for pattern in "${BLOCKED_PATHS[@]}"; do
if [[ "$file_path" == *"$pattern"* ]]; then
echo "{\"hookSpecificOutput\": {\"permissionDecision\": \"deny\"}, \"systemMessage\": \"Blocked: writing to sensitive file $file_path\"}" >&2
exit 2
fi
done
# Check content for secrets
if [ -n "$content" ]; then
# AWS keys
if echo "$content" | grep -qE 'AKIA[0-9A-Z]{16}'; then
echo "{\"hookSpecificOutput\": {\"permissionDecision\": \"deny\"}, \"systemMessage\": \"Blocked: content contains AWS access key\"}" >&2
exit 2
fi
# Private keys
if echo "$content" | grep -qE 'BEGIN (RSA |EC |DSA )?PRIVATE KEY'; then
echo "{\"hookSpecificOutput\": {\"permissionDecision\": \"deny\"}, \"systemMessage\": \"Blocked: content contains private key\"}" >&2
exit 2
fi
# Generic API key patterns
if echo "$content" | grep -qE '(api[_-]?key|api[_-]?secret|access[_-]?token)\s*[:=]\s*["\x27][a-zA-Z0-9]{20,}'; then
echo "{\"systemMessage\": \"Warning: content may contain hardcoded API key. Consider using environment variables.\"}"
fi
fi
exit 0
File Organization
Recommended .claude/ structure for a medium-complexity project:
.claude/
├── settings.json # Permissions, hooks, env
├── settings.local.json # Personal overrides (gitignored)
├── CLAUDE.md # Or CLAUDE.md at the project root
├── skills/ # Project skills (new format)
│ ├── review/
│ │ └── SKILL.md
│ ├── test/
│ │ └── SKILL.md
│ └── deploy/
│ └── SKILL.md
├── commands/ # Legacy skills (still work)
│ └── ...
├── agents/ # Project agents
│ ├── code-reviewer.md
│ ├── test-writer.md
│ └── security-scanner.md
└── rules/ # File-scoped rules
├── api.md
├── database.md
└── tests.md
For personal (user-scope) use — a similar structure in ~/.claude/:
~/.claude/
├── settings.json
├── CLAUDE.md
├── skills/ # Global skills
│ ├── debug/
│ │ └── SKILL.md
│ ├── git-workflow/
│ │ └── SKILL.md
│ └── morning-standup/
│ └── SKILL.md
├── agents/ # Global agents
│ ├── senior-reviewer.md
│ └── performance-profiler.md
└── hooks/ # Hook scripts
├── protect-files.sh
├── auto-format.sh
└── validate-commit.sh
Summary
Skills, Agents, Hooks, Memory, and Dynamic Workflows are the five core mechanisms for extending Claude Code, each at its own level:
- Skills — slash commands for repeatable tasks with a predictable format. Invoked manually or automatically. Stored in
.claude/skills/<name>/SKILL.md. - Agents — isolated subprocesses for complex, multi-step tasks. Return only the result. Support
skills,permissionMode,mcpServers,hooks, andinitialPrompt. - Hooks — automatic reactions to events (27+ event types). For enforcing rules and integrating with external tools. Handlers:
command,http,mcp_tool,prompt,agent. - Memory — persistence across sessions. Claude learns from corrections and doesn’t repeat mistakes.
- CLAUDE.md — declarative instructions defining Claude’s behavior in the project.
- Dynamic Workflows — JavaScript orchestration of hundreds of parallel subagents for large-scale tasks. Written by Claude, runs in the background. Available on Max, Team, Enterprise.
- Agent Teams — multiple Claude instances working in parallel, coordinated through a shared task list. Experimental, requires enabling via
CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS. - Plugins — bundled packages (skills + MCP + agents) distributed through a marketplace.