🎯What you get here
Know EXACTLY where to put each piece of Claude Code configuration. Move from “I threw everything into CLAUDE.md” to putting settings, hooks, slash commands, and permissions in the right places — where they work.
Detailed content
📜 CLAUDE.md — hierarchy and scope
CLAUDE.md exists at three levels, all concatenated into the system prompt in order. Getting the hierarchy wrong can make project instructions override global ones without you noticing, or worse — global instructions can drown out project-specific preferences.
The 3 levels (from most general to most specific)
~/.claude/CLAUDE.md ← Global (você, todos os projetos) ↓ concatena ./CLAUDE.md ← Projeto (raiz) ↓ concatena ./src/api/CLAUDE.md ← Subdir (escopo desta pasta)
When Claude opens a file in src/api/, see all 3 files. When you open one in src/ui/, you see only the first 2 (global + project).
✓ Good CLAUDE.md
- • LITERAL build/test/lint commands at the top
- • Non-obvious conventions (don't repeat what the linter already enforces)
- • Links to deep ADRs/runbooks
- • Preferred tone of voice in responses
- • < 2KB (fits without scrolling)
✗ Bloated CLAUDE.md
- • Repeats the entire style guide (which is already in
.editorconfig) - • Project history (irrelevant to the agent)
- • HR policy (not a code instruction)
- • 50+ KB of generic "best practices"
- • Internal library documentation
💡Golden rule
If the content can be read on demand (reference), put it in references/ of a skill or in docs/ from the project. If it’s always necessary (build commands, core conventions), put them in CLAUDE.md. Default: everything goes in references/, unless proven otherwise.
Key concepts
Global, project, subdir
Everything goes into the prompt
Specific wins
Fit without scrolling
📂 Complete .claude/ folder structure
The convention is strict: the right name, the right folder, or Claude won't see it. Here's the map you can print and tape next to your monitor:
.claude/ ─ raiz do projeto (também ~/.claude/ global) ├── CLAUDE.md ─ instruções (pode estar na raiz do projeto) ├── settings.json ─ permissões, modelo, env, hooks ├── settings.local.json ─ override local (.gitignore) │ ├── agents/ ─ SUB-AGENTS em Markdown │ ├── code-reviewer.md │ └── doc-writer.md │ ├── skills/ ─ SKILLS (pastas com SKILL.md) │ └── my-skill/ │ ├── SKILL.md ─ frontmatter + body │ ├── scripts/ ─ scripts auxiliares │ ├── references/ ─ docs lazy-load │ └── assets/ ─ imagens/binários │ ├── commands/ ─ SLASH COMMANDS │ ├── review.md ─ /review │ ├── ship.md ─ /ship │ └── plugin/sub.md ─ /plugin:sub (namespaced) │ ├── hooks/ ─ scripts disparados em eventos │ ├── pre-commit.sh │ └── on-stop.sh │ └── output-styles/ ─ estilos de resposta └── concise.md
Global vs. project — same structure
All of this exists the same way in ~/.claude/ (your preferences, apply to every project) and in ./.claude/ (specific to that project, committed to git). Project skills/agents take precedence over global ones when the names match.
⚠️Common path errors
- • Put the skill in
.claude/skill/(singular) → Claude doesn't see - • Lowercase SKILL.md → not recognized
- • Sub-agent in
.claude/sub-agents/→ has to beagents/ - • Slash command without
.md→ ignored
Key concepts
Right Name, Right Folder
Global = project
Project > global
.local.json outside
⚙️ settings.json — what you control
JSON file with behavioral configuration. This is where you reduce permission friction, switch models, and inject hooks. Cascading override: user (~/.claude/) → project (.claude/) → local (.claude/settings.local.json).
commented settings.json (real example)
{
"model": "claude-opus-4-6", // modelo padrão da sessão
"includeCoAuthoredBy": true, // Co-Authored-By em commits
"permissions": {
"allow": [
"Bash(ls:*)", "Bash(cat:*)", // libera leitura
"Bash(git status:*)", "Bash(git log:*)", // git read-only
"Read", "Grep", "Glob" // tools básicas
],
"deny": [
"Bash(rm -rf:*)", // nunca
"Bash(curl:* | sh)" // pipe pra shell = não
],
"ask": [
"Bash(git push:*)", // sempre confirma
"Write", "Edit" // escrita = confirma
]
},
"env": {
"CLAUDE_PROJECT_DIR": "${cwd}",
"NODE_ENV": "development"
},
"hooks": {
"PreToolUse": [{
"matcher": "Bash",
"hooks": [{
"type": "command",
"command": "./scripts/log-bash.sh"
}]
}]
}
}
user
~/.claude/settings.json
Your preferences across all projects. Model, theme, tone of voice.
project
.claude/settings.json
It goes into git. Permissions and hooks the whole team inherits.
local
.claude/settings.local.json
Local override (.gitignore). Credentials, dev env.
Key concepts
Each one overrides
3 permission verbs
${cwd}, ${env}
Glob per tool
🪝 Hooks — the only way to guarantee behavior
Hooks are shell commands triggered by the harness in agent events. They RUN; they don’t depend on Claude remembering to do it. It’s the only way to guarantee determinism ("always lint before commit").
PreToolUse — before each tool
Runs before for Claude to run a tool. It can block (exit ≠ 0) or just log.
Classic use case: block dangerous commands, log every Bash command, redirect Read to indexed MCP.
PostToolUse — after each tool
Runs then. Receives the tool output and can annotate context for future rounds.
Classic use case: run a formatter after Edit, validate JSON after Write, index the changed file.
Stop — when the agent decides to stop
Runs when Claude finishes the turn. Allows a final check.
Classic use case: run tests, validate the diff before handing back control, require a completed checklist.
SessionStart and UserPromptSubmit
SessionStart: runs when you open a session. UserPromptSubmit: with each message you send.
Classic use case: SessionStart populates MCP, UserPromptSubmit injects additional context (claude-mem, etc.).
💡Memory does NOT replace a hook
When you ask it to "always do X," Claude may forget (it's not deterministic). A hook RUNS. Asked it to run lint before committing? Hook. Asked it to log commands? Hook. Skill memory helps, but for a guarantee, use a hook.
Key concepts
Always run
0 ok, ≠0 blocks
Error policy
Filter by tool
⚡ Custom slash commands
Markdown files in .claude/commands/ that automatically become slash commands. A task you repeat? It becomes /comando and disappears.
Example — .claude/commands/review.md
--- description: Revisa o diff atual procurando bugs de correção allowed-tools: Bash(git diff:*), Read, Grep --- Revise o diff atual da branch. Procure: - Bugs de correção (não estilo) - Casos não tratados (null, vazio, edge) - Vulnerabilidades comuns (SQLi, XSS, path traversal) Use \`$ARGUMENTS\` se passado para focar em arquivo específico. Retorne uma lista numerada de findings + severity.
Usage: /review or /review src/api/auth.ts
✓ Good slash command use cases
- •
/review— reviews the current diff - •
/ship— pre-merge checklist - •
/test— generates tests for the open file - •
/explain— explains the selected passage - •
/changelog— generates a CHANGELOG entry
✗ Poor slash command use
- • Huge content that should be a skill
- • A command that only makes sense for you (use user-level, not project-level)
- • No allowed-tools (anything goes)
- • No description (you only find out by reading the file)
Key concepts
Command arguments
Restrict surface
/plugin:sub
Slash scope
🔐 Permission system — friction vs. security
Three verbs: allow (unlocks), deny (blocks), ask (asks). Poorly calibrated configuration creates friction (asking about everything) or risk (allowing too much).
Session modes
Independent of the permissions of settings.json, you can switch MODES live:
- default: use the exact settings
- acceptEdits: accepts Edit/Write without asking (useful in refactoring)
- plan: only plans, never edits (useful in architecture)
- bypassPermissions: ignores everything (dangerous — only for a sandbox environment)
Key concepts
allow/deny/ask
Bash(cmd:*)
plan, acceptEdits
mcp__server__
🧪 Plan mode and output styles
Two mechanisms for switching behavior live without editing settings. Plan mode freezes editing (Claude plans, doesn’t act). Output styles change the response tone (concise, verbose, explanatory, etc.).
📋 Plan mode
Activated by /plan or flag --plan. Claude reads, thinks, proposes—but doesn’t write or run anything destructive until you exit the mode.
When to use: major refactor, architectural choice, bug hypothesis. You want alignment before taking action.
🎨 Output styles
Activated by /output-style concise. Live in .claude/output-styles/<nome>.md. They change the tone without touching the system prompt.
Built-in: concise (goal-oriented), verbose (detailed), explanatory (teaching-focused). Customize by creating your own.
💡Practical combo
Starting a new architecture task? Go to /plan + /output-style verbose. Claude designs everything, you review it, then you exit plan mode and it executes.
Key concepts
You don't need to edit settings
Reads only, doesn't write
Response tone
.md in output-styles/
🎯Module summary
Next module:
2.2 — Skills, sub-agents, and MCP in Claude Code