Table of Contents
====== Claude Code — Working Reference ======Scope: current behaviour as of late Oct 2026 (release line v2.1.3xx). Built from the official docs at code.claude.com and the 7-part listening series. Version-specific details drift fast: check /release-notes or the changelog when something behaves differently.
Conventions on this page: monospace = literal command, flag, file or setting. “Agent” = the model doing the work. “Harness” = Claude Code itself (the program that runs tools, hooks and permission checks).
~~TOC~~
1. Mental model
==== 1.1 Two kinds of instruction ====Every instruction is either read by the model (which may decide otherwise) or enforced by the harness (which always applies it).
| Concern | Non-deterministic: model decides | Deterministic: harness enforces | What to do | prompt, CLAUDE.md, skills the model picks up | hooks; skills only a user can start | What it can touch | auto-mode classifier | deny rules, sandbox in strict mode, managed settings | When it is done | request for evidence, /goal, /code-review | tests, typecheck, Stop hook, CI | How much it spends | effort level, the model's own pacing | --max-turns, --max-budget-usd (with -p), spend limits | Final word | the agent's own summary | branch protection, a human approving the merge | |||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Rules of thumb * Default to letting the model decide. Most guidelines have exceptions and the model, with the code in front of it, judges them better than a rule written in advance. * Use the deterministic layer for the few things that must always or never happen. * If you keep adding emphasis to a CLAUDE.md line and it is still missed, the line belongs in a hook. * The reverse also holds: hooks that encode mere preferences should be deleted.
==== 1.2 Four failure modes ====^ Symptom ^ Cause ^ Fix (section) ^| Built the wrong thing, or rediscovers the same fact every session | missing information that is not in the repo | write it down: CLAUDE.md, rules, skills (6, 7) || Said “done” and was not | no way to check its own work | give it a pass/fail check (3) || Did something forbidden, or skipped a mandatory step | a prompt cannot guarantee either | hooks, deny rules, sandbox (4, 8) || Correct but too slow, costly or prompt-heavy | a default does not fit the task | change mode, effort, model, subagent use (1.4, 8, 9) |
==== 1.3 What the defaults already do ==== * Interactive terminal and VS Code sessions start in auto mode: a classifier reviews risky actions instead of prompting you. * Model: Opus 5.5 at medium effort on most plans and providers. * Delegates to subagents when it sees a reason (Explore for wide searches, forks for side tasks), in the background by default. * Compacts the conversation automatically before the context window fills (1M-token window on most current models).
==== 1.4 Effort, model, wording ==== * Effort is the thinking control. /effort low|medium|high|xhigh|max. * high/xhigh: easy-to-overlook cases — bugs in unfamiliar code, flaky tests, schema changes with many readers. * low: rapid back-and-forth you review anyway — brainstorming, sketches, small renames. * max: hard unattended problems (e.g. vulnerability hunting). Overthinks ordinary tasks. * ultrathink in a prompt: deeper reasoning for that one turn without changing the setting. * “think hard”, “be thorough”, “step by step” are ordinary text. They nudge within the effort level, never above it. * “be ambitious” still helps: it tells the agent about scope (edge cases, error states, follow-ons), which only you know. * Models: Opus 5.5 default; Sonnet cheaper for routine work; Haiku for simple subagent jobs; Fable 5.1 only when selected explicitly (/model fable).
==== 1.5 Advice you can drop ====^ Old advice ^ Why it is obsolete ^| Manage the context window aggressively | 1M window plus auto-compaction. Still /clear between unrelated tasks for focus and cost. || IMPORTANT / ALL CAPS | Current models follow plain wording; emphasis causes over-application. Unbendable rule → hook or deny. || Subagents to protect context | Rarely the constraint now. Use them for parallelism, noise isolation, independent review. || Delegate for a better answer | Same or smaller model, same task. A fresh reviewer helps; delegation alone does not. || “think harder” keywords | Effort is the control; ultrathink for one turn. || “keep going / don't be lazy” | Causes over-work. Give a check instead; use /goal or a Stop hook for unattended runs. || Describe architecture in CLAUDE.md | The agent reads the repo. Only write what is not there. |
==== 1.6 Steering a live session ==== * Watch the first minute. Esc stops mid-action and keeps work so far. * /rewind (or Esc twice on an empty prompt): roll code, conversation, or both back to an earlier prompt. Makes the bold attempt cheap. * Checkpoints only cover edits made with the file tools in the main conversation. Files changed by Bash are not restored. Not a git replacement. * After two failed corrections: /clear and write one better prompt instead of a third correction. * /btw: quick side question, not added to history. * /rename <n> then claude --resume <n> for multi-day work; claude --continue resumes the latest. * /usage: where tokens went (by skill, subagent, plugin, MCP server). * /compact <focus>: summarise with a focus. Expensive on a long session with a cold cache. * Prompt cache lasts about 1 hour on a subscription, 5 minutes on API keys/cloud providers/subagents.
2. Giving it the right information
==== 2.1 The test for what to write down ==== - Could it find this by reading the code? - Would it actually go and look?If both are yes, leave it out. Write down what was never in the repo (a meeting decision, a deploy process in someone's head, a required env var) and what takes minutes of digging every session.
==== 2.2 Specific prompts ====^ Instead of ^ Try ^| “fix the login bug” | “users report login fails after session timeout. look at token refresh in src/auth/, write a failing test that reproduces it, then fix it” || “add a calendar widget” | “follow the pattern in HotDogWidget.php, build a calendar widget with month picker and year paging. no new libraries” | * Hand over material instead of describing it: @path includes a file; paste screenshots; pipe output (cat error.log | claude -p "what's going on"). * State your preference between two reasonable approaches up front. * Vague prompts are fine when exploring; expect more correction.
==== 2.3 Interview first, then build ====
I want to add rate limiting to the public API but haven't thought it through.Interview me until you could write the spec, then write it to SPEC.md.
Then start a fresh session to build from SPEC.md: clean context plus a written definition of done that a reviewer can check against later.
==== 2.4 Connecting other systems ==== * Prefer a CLI when one exists (gh signed in = PRs and review comments with no explanation). For unfamiliar CLIs, point at --help. * Otherwise MCP: claude mcp add --transport http notion https://mcp.notion.com/mcp; manage in /mcp. * Connected MCP servers add tool definitions to context even when unused: disable the ones you do not need. * Typed languages: a code-intelligence plugin lets it jump to definitions instead of reading many files.
3. Proving the work is done
==== 3.1 Why “done” fails ====The agent stops when the work looks done. Without something to run that returns pass/fail, you become the test suite. Give it a check and it closes the loop itself: change → run check → read failure → fix → rerun.
Valid checks: a test file, a build exit code, a linter, a script diffing output against a fixture, a browser screenshot beside the mockup. The single most useful line in CLAUDE.md is the command that runs your check.
==== 3.2 Strictness ladder ====^ Rung ^ Mechanism ^ Who decides done ^| 1 | In the prompt: “run the auth tests and keep going until they pass” | the working model || 2 | /goal <condition> | a separate evaluator model, every turn || 3 | Stop hook (command type) | your script; harness enforces || 4 | /code-review or a reviewer subagent | a fresh context that never saw the reasoning |
==== 3.3 /goal in detail ==== * /goal all tests in test/auth pass and the lint step is clean — starts a turn immediately; the condition is the instruction. * After each turn, the configured small fast model (Haiku by default on the Anthropic API) judges the condition against the transcript and returns: * not yet met — work continues; the reason becomes guidance for the next turn. * met — goal clears; “achieved” entry recorded. * impossible — goal clears; “failed” entry with the reason. * Implemented as a session-scoped prompt-based Stop hook. So it is model-judged (soft), not deterministic. * The evaluator does not run commands or read files. It only sees what the agent surfaced in the conversation. Write conditions the agent's own output can prove. * Strong condition = one measurable end state + a stated check (npm test exits 0, git status is clean) + constraints (no other test file is modified). * Max 4,000 characters. Bound the run with a clause: or stop after 20 turns. * /goal (no args) = status: condition, elapsed time, turns, token spend, last reason. Ctrl+O shows each verdict's reasoning. * /goal clear (aliases: stop, off, reset, none, cancel). /clear also removes it. Resuming a session restores an active goal (counters reset). * Does not change the permission mode. For unattended turns run it in auto mode; in Manual mode it waits on prompts. * Headless: claude -p "/goal CHANGELOG.md has an entry for every PR merged this week". Add --output-format stream-json --verbose to see progress. * Clears the goal (you must fix): auth failure (when Claude Code manages credentials), exhausted credit, unrecoverable context overflow, model unavailable. * Keeps the goal: transient errors retry up to 3 times, then pause; rate/usage limits pause; resumes when a usage limit resets if auto-continue is on. * Background work (subagent, background shell) defers evaluation. After 30 min waiting, a check-in asks the agent to inspect running tasks; later check-ins back off (×2, capped at ×4). CLAUDE_CODE_GOAL_CHECKIN_MINUTES changes the interval; 0 disables check-ins and auto-retries. * Stall guard: several turns with no tool use → loop stops, goal stays set. * Unavailable when disableAllHooks is true or allowManagedHooksOnly is set; subject to workspace trust like hooks. * Official view: rarely needed interactively; valuable for long background runs where the agent ends a turn with a progress summary while items remain.
==== 3.4 Keeping a session running: compare ====^ Mechanism ^ Next turn starts when ^ Stops when ^ Scope ^| /goal | previous turn finishes (or check-in/retry) | evaluator says met/impossible, error you must fix, or /goal clear | this session || /loop | a time interval elapses | you stop it, or the agent decides it is done | this session || Stop hook | previous turn finishes | your script or prompt decides | every session in its settings scope |Auto mode removes per-tool prompts; /goal removes per-turn prompts. They are complementary.
==== 3.5 Stop hook that enforces a typecheck ====
{ "hooks": { "Stop": [ { "hooks": [ { "type": "command", "command": "pnpm tsc --noEmit 1>&2 || exit 2" } ] } ] }}
* Exit 2 blocks the stop; stderr is sent back as the reason (hence 1>&2). * Override after 8 consecutive blocks with no tool call between them. Raise with CLAUDE_CODE_STOP_HOOK_BLOCK_CAP.
==== 3.6 Evidence and review ==== * Always ask for evidence: the command run and its output, or the screenshot. For unwatched sessions it is the only evidence. * /verify: builds and runs the app and checks the change against the running app, not just tests. * /code-review: reviews the diff in a fresh subagent. * Review against intent:
use a subagent to review the rate limiter diff against SPEC.md, check every requirementis implemented and the listed edge cases have tests, report gaps that affect correctnessand skip style
* Keep “skip style”: a reviewer asked to find problems always finds some; fixing all of them adds abstraction and impossible-case tests.
4. Hooks
==== 4.1 What a hook is ====A user-defined handler the harness runs at a fixed lifecycle point. The model does not choose to run it and cannot skip it. Used for: enforcing rules, automating repetitive steps, integrating tools.
==== 4.2 Configuration shape ====Three nesting levels in a settings file: - Event — lifecycle point (PreToolUse, Stop…). - Matcher group — filter (e.g. only the Bash tool). - Handler(s) — what runs.Optional per-handler if (permission-rule syntax, tool events only) skips spawning unless the call matches, e.g. "if": "Bash(git *)" or "if": "Edit(*.ts)".
{ "hooks": { "PreToolUse": [ { "matcher": "Bash", "hooks": [ { "type": "command", "if": "Bash(rm *)", "command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/block-rm.sh", "args": [] } ] } ] }}
Matcher rules * *, empty or omitted = match all. * Only letters/digits/_/-/space/comma/pipe = exact name or list (Edit|Write, Edit, Write). * Anything else = unanchored JavaScript regex (Edit.* also matches NotebookEdit; anchor with ^…$). * MCP tools: mcp__<server>__<tool>. All tools of a server: mcp__memory__.* (the .* is required).
==== 4.3 Events ====Cadence: per session (SessionStart, SessionEnd); per turn (UserPromptSubmit, Stop, StopFailure); per tool call (PreToolUse, PostToolUse).
| Event | Fires | Can block? | SessionStart | new session, resume, /clear, compaction, fork (matcher: startup/resume/clear/compact/fork) | no (adds context) | UserPromptSubmit | before a prompt reaches the model (also scheduled/loop turns) | yes | PreToolUse | before a tool runs | yes | PermissionRequest | when a call would prompt you | via JSON decision only | PermissionDenied | auto mode denied a call | no (can allow retry) | PostToolUse | after a tool succeeds | no (tool already ran; stderr shown to agent) | PostToolUseFailure | after a tool fails | no | PostToolBatch | after a batch of parallel calls | yes (stops loop) | Stop | agent finishes responding | yes (forces continuation) | SubagentStart / SubagentStop | subagent spawned / finished | Stop variant can block | PreCompact / PostCompact | around compaction | Pre can block | Notification | agent needs attention (permission_prompt, idle_prompt…) | no | InstructionsLoaded | a CLAUDE.md or rules file loads | no (good for debugging) | ConfigChange | a config file changes mid-session | yes | CwdChanged / FileChanged | directory change / watched file change | no | WorktreeCreate / WorktreeRemove | worktree lifecycle | yes | SessionEnd | session terminates | no | |||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
==== 4.4 Handler types ====^ Type ^ What it does ^ Deterministic? ^ Default timeout ^| command | shell command; JSON on stdin | yes | 600 s || http | POSTs the JSON to a URL | yes | 600 s || mcp_tool | calls a tool on a configured MCP server | yes | 600 s || prompt | single-turn model judgement | no | 30 s || agent | subagent with read/search tools judges (experimental) | no | 60 s | * UserPromptSubmit handlers default to 30 s (they block every prompt). SessionEnd hooks share a 1.5 s budget. * Matching hooks run in parallel. One hook's deny does not stop sibling hooks from running. * For real enforcement use command or http.
==== 4.5 Input contract ====JSON on stdin (command) or as the POST body (http). Common fields: session_id, prompt_id, transcript_path, cwd, permission_mode, effort, hook_event_name; plus agent_id/agent_type inside subagents. Tool events add tool_name, tool_input, tool_use_id.
{ "session_id": "abc123", "cwd": "/home/me/proj", "permission_mode": "default", "hook_event_name": "PreToolUse", "tool_name": "Bash", "tool_input": { "command": "npm test" } }
Note: transcript_path may lag the current turn; on Stop use last_assistant_message. Manual mode arrives as "default".
==== 4.6 Output contract: exit codes ==== * Exit 0 = success / no objection. Any valid JSON on stdout is applied. On PreToolUse, exit 0 is not approval — the normal permission flow still runs. * Exit 2 = blocking error on events that can block. stderr goes back as the reason. This feedback loop is what lets the agent adapt. * Any other code (including 1) = non-blocking error; the action proceeds. A policy script that exits 1 enforces nothing. * On UserPromptSubmit, SessionStart, UserPromptExpansion and PostModelSwitch, plain-text stdout on exit 0 is added to the agent's context.
==== 4.7 Output contract: JSON ====Exit 0 and print exactly one JSON object (nothing else on stdout). * Universal: continue: false + stopReason (halt entirely); systemMessage (warning to user); terminalSequence (desktop notification/title/bell via allowed OSC sequences). * PreToolUse via hookSpecificOutput:
{ "hookSpecificOutput": { "hookEventName": "PreToolUse", "permissionDecision": "deny", "permissionDecisionReason": "Database writes are not allowed" } }
* permissionDecision: allow (skip prompt) / deny / ask (force prompt) / defer (-p only, for SDK wrappers). * Multiple hooks: most restrictive wins — deny > defer > ask > allow. * A hook's allow does not override deny or ask rules in settings. A hook's deny holds in every mode, including bypassPermissions. * updatedInput rewrites tool arguments before execution (avoid two hooks rewriting the same tool). * PostToolUse: updatedToolOutput replaces the result (redaction point); top-level decision: "block" + reason. * Stop/SubagentStop: decision: "block" + reason to continue. * PermissionRequest: hookSpecificOutput.decision.behavior allow/deny, optional updatedPermissions. * additionalContext (inside hookSpecificOutput) injects a system reminder: SessionStart/SubagentStart (start), UserPromptSubmit (with prompt), tool events (beside result), Stop (end of turn). * Write it as plain facts (“Deploy target is staging”), not system-style commands — those can trip prompt-injection defences. * Strings over 10,000 chars are spilled to a file; only a 2,000-char preview stays.
==== 4.8 Failure semantics (critical) ==== * Hooks fail open by default. Script missing, crash, timeout, invalid JSON → the action goes ahead (non-blocking error notice). * For guards, set "onFailure": "block" on command or http hooks: any failure then acts like exit 2 (on PermissionRequest, denies). * Not applicable to Stop/SubagentStop/TaskCompleted/TeammateIdle or async hooks. * The if filter is best-effort: when the harness cannot parse what a shell command runs, the hook fires anyway. Use permission rules, not hooks, for hard allow/deny on commands. * A hook that decides in a background process must print its decision first and redirect the background process's output.
==== 4.9 Where hooks live ====^ Location ^ Scope ^ Shared ^| ~/.claude/settings.json | all your projects | no || .claude/settings.json | project | yes (commit) || .claude/settings.local.json | project | no || managed policy settings | organisation | admin-controlled || plugin hooks/hooks.json | while plugin enabled | yes || skill frontmatter | rest of session after invocation (once: true for single run) | yes || subagent frontmatter | while that subagent runs (Stop becomes SubagentStop) | yes | * Hooks merge across levels; managed hooks cannot be disabled from lower levels. * "disableAllHooks": true disables all (no per-hook disable). Per run: --settings '{"disableAllHooks": true}' . * Project hooks only run after the folder's workspace trust is accepted (but see -p caveats in 8.10). * /hooks = read-only browser showing each hook and its source.
==== 4.10 Patterns ====Auto-format after edits (.claude/settings.json):
{ "hooks": { "PostToolUse": [ { "matcher": "Edit|Write", "hooks": [ { "type": "command", "command": "jq -r '.tool_input.file_path' | xargs npx prettier --write" } ] } ] } }
Protect files (.claude/hooks/protect-files.sh, registered on PreToolUse matcher Edit|Write):
#!/bin/bashINPUT=$(cat)FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')for p in ".env" "package-lock.json" ".git/"; do if [[ "$FILE_PATH" == *"$p"* ]]; then echo "Blocked: $FILE_PATH matches protected pattern '$p'" >&2 exit 2 fidoneexit 0
chmod +x it; a non-executable script is a silent non-blocking failure.
Desktop notification when input is needed (~/.claude/settings.json):
{ "hooks": { "Notification": [ { "matcher": "", "hooks": [ { "type": "command", "command": "notify-send 'Claude Code' 'Needs your attention'" } ] } ] } }
Re-inject context after compaction:
{ "hooks": { "SessionStart": [ { "matcher": "compact", "hooks": [ { "type": "command", "command": "echo 'Reminder: use Bun, not npm. Run bun test before committing.'" } ] } ] } }
Load direnv into the agent's shell: SessionStart and CwdChanged hooks running direnv export bash > "$CLAUDE_ENV_FILE". The env file is sourced before every Bash command.
Stop hook loop guard:
INPUT=$(cat)[ "$(echo "$INPUT" | jq -r '.stop_hook_active')" = "true" ] && exit 0
Auto-approve one prompt type (keep the matcher narrow):
{ "hooks": { "PermissionRequest": [ { "matcher": "ExitPlanMode", "hooks": [ { "type": "command", "command": "echo '{\"hookSpecificOutput\":{\"hookEventName\":\"PermissionRequest\",\"decision\":{\"behavior\":\"allow\"}}}'" } ] } ] } }
==== 4.11 Debugging ==== * /hooks — is it listed under the right event? * Pipe sample JSON by hand: echo '{"tool_name":"Bash","tool_input":{"command":"ls"}}' | ./my-hook.sh; echo $? * claude --debug-file /tmp/claude.log then tail -f; or /debug mid-session. * Ctrl+O transcript view shows hook outcomes. * Silent failure 1: shell profile echoes text before the JSON → output treated as plain text. Guard echoes with if [[ $- == *i* ]]. * Silent failure 2: decision fields placed at top level instead of inside hookSpecificOutput → ignored. Debug log says “unrecognized keys”. * Use absolute paths or ${CLAUDE_PROJECT_DIR}; exec form ("args": []) avoids shell quoting.
5. Folders and files
==== 5.1 Project folder (commit to git) ====^ Path ^ Purpose ^| CLAUDE.md or .claude/CLAUDE.md | instructions loaded every session || CLAUDE.local.md | private per-project instructions; add to .gitignore || .claude/settings.json | permissions, hooks, env vars, model defaults (shared) || .claude/settings.local.json | personal overrides; “don't ask again” approvals land here || .claude/rules/*.md | topic rules, optionally path-scoped || .claude/skills/<n>/SKILL.md | skills || .claude/commands/*.md | older single-file commands (same mechanism as skills) || .claude/agents/*.md | custom subagents || .claude/workflows/*.js | dynamic workflow scripts; each becomes /<n> || .claude/output-styles/*.md | response-shaping instruction sets || .claude/agent-memory/<n>/ | subagent persistent memory (project scope) || .mcp.json | team-shared MCP servers || .worktreeinclude | gitignored files to copy into new worktrees |
==== 5.2 Home folder ~/.claude/ ==== * Personal equivalents: CLAUDE.md, settings.json, rules/, skills/, agents/, output-styles/, keybindings.json, themes/. * ~/.claude.json: app state, account, UI toggles, personal MCP servers, per-project trust. * plugins/: installed plugins and marketplaces. * CLAUDE_CONFIG_DIR relocates everything.
==== 5.3 The projects subfolder ====~/.claude/projects/<project-path-with-non-alphanumerics-as-dashes>/ * <session>.jsonl — full transcript: every message, tool call, tool result. Powers resume, continue, rewind. * <session>/subagents/agent-<id>.jsonl — subagent transcripts (+ .meta.json). * <session>/tool-results/ — large outputs spilled from context. * memory/ — auto memory (MEMORY.md + topic files).
Retention and privacy * Transcripts and most session data are deleted after cleanupPeriodDays (default 30, minimum 1). Memory is exempt. * Plaintext, not encrypted. If a tool reads .env or a command prints a token, it is on disk. Mitigate: lower retention, CLAUDE_CODE_SKIP_PROMPT_HISTORY, --no-session-persistence with -p, deny reads of secret files. * claude purge <path> [--dry-run] [--yes] [--all] [-i] — deletes a project's transcripts, memory, matching history and config entry; shows the plan first. * Other data: history.jsonl (prompt recall, Ctrl+R), file-history/ (checkpoint snapshots), plans/, debug/, paste-cache/, tasks/. * Per-session scratchpad lives under the temp dir (/tmp/claude-<uid>/<project>/<session>/scratchpad/ on Linux): throwaway files, no permission prompts, removed with the transcript.
6. Instructions and memory
==== 6.1 CLAUDE.md locations and load order ====^ Scope ^ Location ^ Shared with ^| Managed policy | Linux/WSL /etc/claude-code/CLAUDE.md; macOS /Library/Application Support/ClaudeCode/CLAUDE.md | everyone on the machine; cannot be excluded || User | ~/.claude/CLAUDE.md | you, all projects || Project | ./CLAUDE.md or ./.claude/CLAUDE.md | team via git || Local | ./CLAUDE.local.md | you, this project | * Loaded from the working directory and every parent; concatenated, not overriding. Ordered root → cwd, so the nearest file is read last; CLAUDE.local.md follows CLAUDE.md at each level. * Subdirectory CLAUDE.md files load lazily, when the agent reads/edits a file there. * Delivered as a user message after the system prompt: context, not enforced configuration. * After /compact, the root CLAUDE.md is re-read from disk. Instructions given only in chat can be lost. * claudeMdExcludes (glob list, any settings layer) skips other teams' files in monorepos. * --add-dir directories' CLAUDE.md load only with CLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD=1.
==== 6.2 AGENTS.md ==== * No CLAUDE.md/CLAUDE.local.md in cwd or above → AGENTS.md is read automatically. * Both present → only CLAUDE.md (default claude-md-or-agents-md). Change via /config → Project instructions: claude-md-and-agents-md, claude-md, managed-only. * Portable alternative: a CLAUDE.md containing @AGENTS.md plus Claude-specific lines.
==== 6.3 What to write ====Add a line when: the same mistake happens twice; a code review catches something it should have known; you type the same correction as last session; a new teammate would need it.
Good content: * How to confirm work: exact test/typecheck/lint commands; how to run one test file. * Misleading code: legacy patterns not to copy; directories that look dead but are live. * Decisions not in the repo: chosen error helper, deploy flow, migration review rules. * Anything corrected twice.
# Commands- Install: pnpm install- Run one test file: pnpm vitest run path/to/file.test.ts- Typecheck: pnpm tsc --noEmit # Conventions- Use the error helpers in src/lib/errors.ts, never throw raw strings- src/legacy/ is still live but don't copy its patterns into new code # Gotchas- Integration tests need DATABASE_URL set, see .env.example
Style: under 200 lines; concrete and verifiable (“2-space indentation”, not “format nicely”); grouped under headers; no contradictions (the model may pick either side).
Mechanics * @path/to/file imports (relative to the importing file; max depth 4). Organisation only — no context saving. Paths outside the project need one-time approval. Backticks keep a path literal. * Block HTML comments are stripped before injection: free maintainer notes. * /init drafts a starting file (or proposes improvements). CLAUDE_CODE_NEW_INIT=1 for an interactive flow covering CLAUDE.md, skills and hooks. * /doctor proposes trims; /doctor prompt-audit flags stale, broken or contradictory instructions across CLAUDE.md, rules, skills, agents. * Files over 4 MiB are skipped entirely.
==== 6.4 Path-scoped rules ==== * .claude/rules/*.md (recursive). One topic per file. * No frontmatter = loads at session start like CLAUDE.md. * paths: frontmatter = loads only when the agent reads/writes/edits a matching file.
---paths: - "src/api/**/*.ts"---- Validate request bodies with the zod schemas in src/api/schemas/- Every new endpoint needs an entry in openapi.yaml, CI fails without it
* Globs support brace expansion: src/**/*.{ts,tsx}. * User rules in ~/.claude/rules/ load before project rules; neither overrides — keep consistent. * Symlinked shared rule dirs work; targets outside the project need approval. * On-demand files over a per-file limit (40k chars on 200K context; 150k on 1M with current models) are truncated with a “read the rest” note.
==== 6.5 Auto memory ==== * The agent writes notes for itself: user (role, expertise, preferences), feedback (corrections, confirmed approaches), project (decisions/deadlines not derivable from code), reference (where external info lives). Skips anything derivable from code or already in CLAUDE.md. * Location ~/.claude/projects/<project>/memory/; keyed on the git repo, so all worktrees share it. Machine-local. * MEMORY.md index, one line per memory; first 200 lines or 25 KB load each session. Topic files are read on demand. * “Remember X” → auto memory. “Add X to CLAUDE.md” → the shared file. * /memory: list/open all instruction files and the memory folder; toggle auto memory. Per project: "autoMemoryEnabled": false. Env: CLAUDE_CODE_DISABLE_AUTO_MEMORY=1.
==== 6.6 Debugging instructions ==== - /context — is the file under Memory files? - Too long? The line gets lost. - Contradicted elsewhere (other CLAUDE.md, rules)? - Vague? Make it concrete. - Must it always hold? → hook or deny rule. - Conflicts with built-in git guidance? includeGitInstructions, attribution settings. * InstructionsLoaded hook logs exactly which files loaded, when, and why.
7. Skills
==== 7.1 What and why ====A folder with SKILL.md (YAML frontmatter + markdown body) plus optional supporting files. Follows the open Agent Skills standard. Custom commands are merged into skills (.claude/commands/deploy.md and .claude/skills/deploy/SKILL.md both create /deploy).
Progressive disclosure: only name + description sit in context every session; the body loads when invoked (by /name or by the agent judging it relevant).
| Put it in | When | CLAUDE.md | facts true for every task | rules with paths: | facts for one part of the codebase | skill | procedures and task-specific knowledge (release, runbook, doc style) | |||
|---|---|---|---|---|---|---|---|---|---|---|
Write one when you keep pasting the same instructions/checklist, or a CLAUDE.md section has become a procedure. Do not write one for what the model already does well — it adds context and can degrade output. Measure (7.11).
==== 7.2 Locations and precedence ====^ Location ^ Path ^ Loads in ^| Enterprise | managed settings dir .claude/skills/ | all users on managed machines || Personal | ~/.claude/skills/<n>/SKILL.md | your local projects (not cloud/Cowork) || Project | .claude/skills/<n>/SKILL.md | this repo (commit for team) || Nested | <subdir>/.claude/skills/ | once the agent works in that subdir || Plugin | <plugin>/skills/<n>/SKILL.md | as /plugin:skill || claude.ai account | synced to ~/.claude/skills/synced/ | Cowork, cloud, signed-in terminal sessions | * Name clashes: enterprise > personal > project. A local skill replaces a bundled command of the same name (not its aliases). * Cloud sessions and cloud scheduled tasks do not read ~/.claude/skills/. Enable the skill on your account or commit it to the repo. * Edits to SKILL.md are picked up live; new top-level dirs need /reload-skills.
==== 7.3 Frontmatter ====^ Field ^ Use ^| description | most important: what and when; main use case first; words users would say. With when_to_use capped at 1,536 chars in the listing || name | command name (defaults to folder name) || disable-model-invocation: true | only you can run it (deploy, commit, send). Also hides description from context || user-invocable: false | only the agent can load it (background knowledge) || allowed-tools | pre-approves tools for the invoking turn only; not a restriction || disallowed-tools | removes tools while active || model, effort | override for that turn || paths | auto-activate only for matching files || hooks | register hooks for the rest of the session || context: fork + agent | run as a subagent (7.8) || arguments, argument-hint | named arguments and autocomplete hint || shell | bash or powershell for injected commands |
Security note: allowed-tools is not gated by workspace trust — a skill committed to a cloned repo can grant itself broad access, even in -p runs. Read the allowed-tools of repo skills before running there. Managed allowManagedPermissionRulesOnly neutralises it.
Example (user-only, side-effecting):
---name: releasedescription: Cut a new release. Bumps version, writes changelog, tags and pushes so CI publishes.disable-model-invocation: trueallowed-tools: Bash(git add *) Bash(git commit *) Bash(git tag *) Bash(git push *)---1. Ensure you are on main with a clean tree. If not, stop and ask.2. Run `pnpm changeset version` and commit the result.3. Summarise PRs merged since the last tag into CHANGELOG.md, one line each.4. Tag `v<new version>` and push the tag. CI publishes; never publish locally.
==== 7.4 Invocation control ====^ Frontmatter ^ You invoke ^ Agent invokes ^ In context ^| default | yes | yes | description always; body on invoke || disable-model-invocation: true | yes | no | nothing until invoked || user-invocable: false | no | yes | description always; body on invoke |/name args at the start of a message runs it directly; mid-sentence /name only permits the agent to run it.
==== 7.5 Content lifecycle ==== * On invocation the rendered body enters the conversation once and stays; it is not re-read on later turns. Write standing instructions (“run tests after every edit”), not one-time steps. * Re-invoking with identical content adds only a note; changed content (new args/injected output) appends the full body again. * Compaction re-attaches each invoked skill's first 5,000 tokens, sharing a 25,000-token budget filled from the most recent. Put critical lines at the top; re-invoke after compaction if it drifts. * Absolute rules → a hook (can live in the skill's hooks frontmatter).
==== 7.6 Arguments and substitutions ==== * $ARGUMENTS (all), $ARGUMENTS[N] / $N (0-based, shell-style quoting), $name (from arguments:). * No placeholder present → ARGUMENTS: <input> is appended. * ${CLAUDE_SKILL_DIR}, ${CLAUDE_PROJECT_DIR}, ${CLAUDE_SESSION_ID}, ${CLAUDE_EFFORT}, plugin ${CLAUDE_PLUGIN_ROOT}/${CLAUDE_PLUGIN_DATA}. * Escape a literal with backslash: \$1.00.
==== 7.7 Injecting live data ====!`command` (or a fenced block opened with ```!) runs before the model sees the skill; output replaces the placeholder.
---name: pr-summarydescription: Summarize changes in a pull requestcontext: forkagent: Exploreallowed-tools: Bash(gh *)---- PR diff: !`gh pr diff`- PR comments: !`gh pr view --comments`Summarize this pull request...
* Any non-zero exit aborts the whole invocation (except exit 1 from search/compare commands). Append || true where non-zero is normal. * Each command is checked against permission rules; one that would prompt aborts the skill (outside auto mode) — pre-approve via allowed-tools. * Runs in the session shell's cwd, 2-minute timeout, large output spilled to file. * Not executed locally for skills synced from claude.ai. disableSkillShellExecution turns it off (managed).
==== 7.8 Forked skills ==== * context: fork runs the body as a new subagent's prompt. No conversation history — instructions must stand alone; a conventions-only skill gives it nothing to do. * Runs in the background by default; background: false to wait. * agent: Explore or Plan start without CLAUDE.md — put everything needed in the skill. * Background forks edit outside checkpoints; /rewind will not undo them.
==== 7.9 Supporting files ====
my-skill/├── SKILL.md (overview + navigation, < 500 lines)├── reference.md (loaded when needed)├── examples.md└── scripts/helper.py (executed, not loaded)
Link files from SKILL.md so the agent knows when to read them. Pair ${CLAUDE_SKILL_DIR}/scripts/x.sh in the body with allowed-tools: Bash(${CLAUDE_SKILL_DIR}/scripts/x.sh *) to run without a prompt.
==== 7.10 Bundled skills ====/doctor (setup checkup, fixes on confirmation), /doctor prompt-audit, /code-review, /batch, /debug, /loop, /claude-api (migrate, upgrade, cost-optimize, build-eval…), /run, /verify, /run-skill-generator (records your launch recipe as .claude/skills/run-<n>/).If a project skill named verify or simplify exists at session start, built-in commit instructions tell the agent to run it before each commit.
==== 7.11 Managing and measuring ==== * Skill listing budget ~1% of context; overflow drops descriptions of least-used skills first. * /skills — set each to on / name-only / user-only / off (writes skillOverrides to settings.local.json). * /skill-doctor — context cost vs actual use; prune unused. * Permission rules: Skill(name), Skill(name *); deny Skill to disable all. * Evaluate: realistic prompts, each in a fresh session with the skill on and with it off; compare. Tools: skill-creator plugin (/plugin install skill-creator@claude-plugins-official), claude plugin eval for plugin skills (CI gate). * Troubleshoot: not triggering → description keywords, YAML parse (claude plugin validate .claude/skills); triggers too often → narrow description or user-only; drifts → standing wording, re-invoke, hook.
8. Permissions, modes and the sandbox
==== 8.1 Three layers ==== * Rules — which tools/commands/files/domains are allowed, prompted or refused. * Modes — the baseline for everything the rules do not decide. * Sandbox — OS-level confinement of shell commands (filesystem + network), independent of intent.Permissions are enforced by the harness. Prompts and CLAUDE.md shape what the agent tries, not what it is allowed.
==== 8.2 Rule evaluation ==== * Lists: allow, ask, deny under permissions. Manage with /permissions. * Order: deny → ask → allow; first match wins; specificity does not matter. (Unlike a line-ordered ACL, ordering is by verdict class.) A broad deny beats a narrow allow; an ask beats a narrower allow. * Across scopes: a deny anywhere beats an allow anywhere. Managed settings beat everything, including CLI flags. * Bare tool name in deny (Bash) removes the tool from context. Scoped (Bash(rm *)) blocks matching calls only.
{ "permissions": { "allow": ["Bash(npm run *)", "Bash(git commit *)"], "ask": ["Bash(git push *)"], "deny": ["Read(./.env)", "Read(./.env.local)", "Read(./secrets/**)"] } }
==== 8.3 Bash rule syntax ====^ Rule ^ Matches ^ Does not match ^| Bash(npm run build) | exactly that | npm run build --watch || Bash(npm run *) | npm run build, npm run | npm install || Bash(git log *) | all git log | git push || Bash(git *) | every git command, incl. git -c core.fsmonitor=<script> … | — || Bash(ls *) | ls, ls -la | lsof || Bash(ls*) | ls -la, lsof | — | * Put * after the subcommand. Startup warns on a wildcard before the subcommand. * Trailing * with a preceding space also matches the bare command. Bash(ls:*) = Bash(ls *). * Compound commands split on &&, ||, ;, |, |&, &, newline. Allow must match every part; deny/ask fire if any part (incl. subshells, $(), loop bodies) matches. * Stripped wrappers: timeout, time, nice, nohup, stdbuf, command, builtin, noglob, bare xargs, known-safe env assignments. Not stripped: npx, docker exec, direnv exec, devbox run, mise exec — Bash(devbox run *) allows devbox run rm -rf .. * Exec wrappers (watch, setsid, flock) and find -exec/-delete cannot be approved by prefix rules. * Built-in read-only set runs without prompts (ls, cat, grep, find, wc, diff, read-only git, cd within workdirs…). Not configurable; add ask/deny to force prompts. * Redirects (> file, < file, tee) are checked against Edit/Read rules and working directories.
What a Bash rule does NOT stop (text match, not intent):^ Deny rule ^ Stops ^ Misses ^| Bash(curl *) | curl https://x | /usr/bin/curl https://x, sh -c "curl https://x" || Bash(rm *) | rm -rf build/ | /bin/rm -rf build/, bash -c "rm -rf build/" || Bash(git push *) | git push origin main | git -C . push origin main, git "push" origin main |Use the sandbox or a PreToolUse hook when the restriction must hold.
==== 8.4 File, web, MCP, agent rules ==== * Read/Edit use gitignore patterns:^ Pattern ^ Anchors at ^ Example ^| //path | filesystem root | Read(//Users/alice/secrets/**) || ~/path | home | Read(~/.zshrc) || /path | the settings file's source (project: project root; user: ~/.claude/) — not filesystem root | Edit(/src/**/*.ts) || path / ./path | current directory | Read(*.env) | * Bare filenames match at any depth (Read(.env) = Read(**/.env)). * Single-segment dir: as allow, Edit(src/**) = only ./src; as deny/ask, matches any src at depth. * ! negation carves exceptions within one source's list (Read(*.env) then Read(!sample.env)). * A Read deny also blocks Edit/Write on that path. Use Edit(...) not Write(...) for path rules (Write/Glob path rules never match). * Read/Edit denies cover built-in tools and recognised file commands, not scripts that open files themselves → sandbox. * Symlinks: allow requires both requested and resolved paths to match; deny triggers on either. * WebFetch: WebFetch(domain:example.com); *.example.com for subdomains. Allowing WebFetch does not restrict curl. * MCP: mcp__server__* or mcp__server__tool. Subagents: Agent(Explore). Skills: Skill(name). * Parameter rules (deny/ask): Agent(model:opus), Bash(run_in_background:true).
==== 8.5 Permission modes ====^ Mode (config value) ^ Runs without asking ^ For ^| Manual (default) | reads only | sensitive work, unfamiliar code || acceptEdits | reads, edits, mkdir/touch/mv/cp/rm/sed inside working dirs | iterating with review via git diff || plan | reads (+ classifier-approved commands if auto available) | explore before changing; edits blocked until plan approved || auto | everything, after classifier review | long tasks, prompt fatigue || dontAsk | pre-approved tools + reads; everything else denied | CI, locked-down scripts || bypassPermissions | everything except the never-auto list | isolated containers/VMs only; refuses root/sudo | * Shift+Tab cycles (auto → manual → acceptEdits → plan → …). --permission-mode <mode> at launch. permissions.defaultMode in settings (auto/bypassPermissions are ignored in project files). * claude -p and Agent SDK start in Manual: calls needing approval are denied unless pre-approved (--allowedTools) or you pass --permission-mode auto. * Plan approval options: switch to auto, approve edits manually, or keep planning. Ctrl+G edits the plan in your editor. * Admins: permissions.disableAutoMode / disableBypassPermissionsMode = "disable".
==== 8.6 Auto mode in detail ====Decision order per action: - Allow/ask/deny rules resolve immediately (exceptions: protected paths and critical-path rm still go further). - Reads and edits in the working directory are auto-approved (protected paths excepted; first read outside workdirs prompts once). - Everything else → classifier (mostly shell commands and network). - Block → the agent receives the reason (rule category) and adapts.
On entering auto mode, broad allow rules are dropped: Bash(*), wildcard interpreters (Bash(python*)), package-manager run commands, Agent and Monitor allows. Restored on exit. Narrow rules (Bash(npm test)) stay.
Blocked by default (selection): curl|bash; sending sensitive data externally; production deploys/migrations; mass cloud deletion; IAM/repo permission grants; shared infra changes; force push; git reset --hard, git clean -fd, stash drop; amending commits not made this session; terraform/pulumi/cdk destroy; DNS/TLS/secret-manager writes; merging unapproved PRs or disabling CI; printing live credentials; disabling security tests; repointing remotes/API base URLs; pushing secrets to public repos; cross-repo PRs/forks you did not name; writing session transcripts; cloud metadata credential access; tunnels/reverse shells.
Allowed by default: local file work; installing dependencies from lock files; reading .env and using creds with their matching API; read-only HTTP; pushing to branches of the current repo (not deploy-named branches like production, gh-pages); deleting jobs it created; trusted destinations you list.
Configuration — ~/.claude/settings.json only (ignored in project settings):
{ "autoMode": { "environment": [ "$defaults", "Source control: github.com/example-org and every repo under it", "Trusted internal domains: *.internal.example.com" ], "allow": [ "$defaults", "Deploying to the staging namespace is fine, it is isolated and resets nightly" ] } }
Keep "$defaults" in every list or your entries replace the built-ins. /auto-mode-setup drafts the environment block. claude auto-mode defaults prints the full rule lists.
Behaviours * Stated boundaries (“don't push until I review”) are honoured as block signals until you lift them — but re-read from the transcript, so compaction can drop them. Use deny/ask rules for anything important. * Stated approvals clear a block only if they name the action and the dangerous specific (“force-push to feature-x”). * Falls back to prompting after 3 consecutive or 20 total blocks (not configurable). In -p there is no prompt; actions are simply skipped. * /permissions → Recently denied: retry with r. * Classifier requests strip tool results (hostile file/web content cannot address it). Subagents are checked at spawn, per action, and on their final report. * Default classifier model: Sonnet 5 (or server-side review on direct API). CLAUDE_CODE_AUTO_MODE_MODEL to change. * Not a guarantee: use it where you trust the general direction.
==== 8.7 Never auto-approved / protected ====No mode auto-approves: explicit ask rules; org connector tools set to ask; user-interaction tools (AskUserQuestion, requiresUserInteraction MCP tools); recognised critical-path rm/rmdir (root, top-level dirs, home, working dir and its parents, unguarded "$VAR"/*); reads outside workdirs when blockReadsOutsideWorkingDirectories is on. * Rewrite flagged deletes with guards: rm -rf "${DIR:?}"/* or literal paths. * In auto/bypass, the critical-path prompt times out after 2 min (denied).
Protected paths (never silently written outside bypass; allow rules do not pre-approve): .git, .config/git, .vscode, .idea, .husky, .devcontainer, .claude (except worktrees, own plans, memory markdown), .gitconfig, shell rc/profile files, .envrc, .npmrc, .mcp.json, .claude.json, .pre-commit-config.yaml and similar build/tool configs.
==== 8.8 Sandbox ==== * /sandbox (macOS, Linux, WSL2) or "sandbox": {"enabled": true}. Confines Bash, PowerShell and Monitor commands and their children at the OS level: filesystem writes and network. * Merges your Read deny rules and WebFetch(domain:…) rules into its configuration. * Auto-allow (default): sandboxed commands run without prompting even under a bare Bash ask rule; deny rules and content-scoped ask rules (Bash(git push *)) still apply. * Escape hatch: a blocked command may request an unsandboxed retry through the normal permission flow. Strict sandbox mode (/sandbox → Overrides) removes it. * In auto mode, sandboxed network is closed by default; the agent names the hosts a command needs and the classifier approves them per command. * Guidance: use permissions and sandbox for defence in depth; the sandbox still holds if a prompt injection subverts the agent. * Manual + sandbox auto-allow is a classifier-free way to iterate with few prompts.
==== 8.9 Working directories ==== * Access defaults to the launch directory. Extend with --add-dir, /add-dir, or additionalDirectories. * Added directories grant file access, not configuration — except skills, commands and agents from --add-dir//add-dir (not from the settings key). * /cd <path> moves the session and applies the new directory's settings, hooks, MCP, skills (trust prompt lists what it would activate). Cd(...) rules restrict targets. * permissions.blockReadsOutsideWorkingDirectories fences reads in every mode.
==== 8.10 Workspace trust and cloned repos ==== * Project permissions.allow and additionalDirectories apply only after you accept the trust dialog (keyed on repo root). Deny/ask apply immediately. * -p and the SDK never show the dialog. In those runs, project hooks, env, helper commands, skill allowed-tools and .mcp.json servers are still used; project allow rules are not. * Before running -p in a repo you did not write: --setting-sources user (ignore project settings and .mcp.json), or --bare (no hooks, skills, plugins, MCP, CLAUDE.md), or --settings '{"disableAllHooks": true}' , plus disabledMcpjsonServers. * /fewer-permission-prompts mines recent transcripts for common read-only commands and drafts allow rules.
9. Subagents
==== 9.1 What they are and when they pay off ====Separate worker: own context window, own system prompt, own tool set, independent permissions; returns a summary. Requests count against the same usage.
Pays off for: parallel independent work; keeping verbose output (test runs, wide searches) out of the main context; an independent reviewer; restricting tools (read-only reviewer).Costs: tokens per subagent; time to rebuild context the main session already had (can be slower for small tasks). Never a smarter answer by itself.Use the main conversation instead for iterative back-and-forth, shared-context phases, quick targeted changes. Use /btw for questions about current context.
==== 9.2 Built-ins ====^ Agent ^ Tools ^ Notes ^| Explore | read-only | codebase search; thoroughness quick/medium/very thorough; no CLAUDE.md, no git status; one-shot (not resumable) || Plan | read-only | research during plan mode; no CLAUDE.md; one-shot || general-purpose | all subagent tools | exploration + modification, multi-step || claude | all | catch-all; default for background sessions |Disable: "deny": ["Agent(Explore)"]; all delegation: deny Agent.
==== 9.3 What a (non-fork) subagent sees at start ==== * Its own system prompt (custom body replaces the default prompt) + environment details. * The delegation message the main agent writes. * CLAUDE.md hierarchy and git status (except Explore/Plan or omitClaudeMd: true). * Preloaded skills from its skills field. * Not: your conversation history, skills already invoked, files already read, output style, main auto memory.If a rule must reach Explore/Plan, restate it in the delegation prompt.
==== 9.4 Custom subagent file ====
---name: reviewerdescription: Reviews changed files against the spec they were built from. Use after implementing a feature, before opening the PR.tools: Read, Grep, Globmodel: sonnetmemory: project---You're reviewing code you didn't write. Compare the changed files against the spec,check every requirement is implemented and listed edge cases have tests,and report only gaps that affect correctness. Skip style.
^ Field ^ Purpose ^| name, description | required; description drives delegation (“use proactively” encourages it). Keep all descriptions under 15k tokens combined || tools / disallowedTools | allowlist / denylist (denylist applied first). Harness-enforced || model | alias, full ID or inherit. haiku for cheap simple jobs || permissionMode | ignored when parent is in auto/acceptEdits/bypass/plan || maxTurns | cap; output marked partial and resumable || skills | preload full skill content (max 32) || mcpServers | servers only this subagent gets (inline or by name); keeps tool defs out of main context || hooks | active only while running || memory | user (~/.claude/agent-memory/), project (.claude/agent-memory/, recommended), local || isolation: worktree | own temporary git checkout; cleaned if unchanged || background, effort, autoCompactWindow, omitClaudeMd, color, initialPrompt | as named | * Scope priority: managed > --agents JSON > project .claude/agents/ > ~/.claude/agents/ > plugin. * Plugin subagents ignore hooks, mcpServers, permissionMode. * Files without name/description or with bad YAML are silently skipped (--debug shows why). * Invoke: name it in a prompt, @"reviewer (agent)" to force it, or claude --agent reviewer to run the whole session as it.
==== 9.5 Models ====Resolution: per-invocation parameter > frontmatter model > CLAUDE_CODE_SUBAGENT_MODEL > main model. Force one model everywhere with CLAUDE_CODE_SUBAGENT_MODEL + CLAUDE_CODE_SUBAGENT_MODEL_FORCE=1. /tasks shows each subagent's model.
==== 9.6 Background, forks, nesting, limits ==== * Subagents spawned from the main conversation run in the background by default; results arrive as a notification. Permission prompts surface in the main session naming the subagent. * Background subagents get a narrower built-in tool set (Read, Grep, Glob, LSP, Bash, Edit, Write, WebFetch, WebSearch, Skill, Monitor, SendMessage…). * Fork (/subtask <task>, or automatic while fork mode is on): inherits full conversation, system prompt, tools, model, and prompt cache — cheap first request. Cannot spawn forks. Panel below prompt: Enter open, x stop. * To let the main agent wait for a subagent interactively: CLAUDE_CODE_FORK_SUBAGENT=0. * Depth: subagents can nest 3 layers (CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH). * Concurrency: 20 running (CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTS). No total cap. * Resume: the main agent messages a finished subagent by ID/name (SendMessage); it continues with full history. Transcripts in projects/…/subagents/, 30-day retention. * Subagent reports are scanned for instruction-shaped text and labelled; this does not replace tool restrictions.
==== 9.7 Patterns ==== * Isolate noise: “Use a subagent to run the test suite and report only failing tests with errors.” * Parallel research: “Research the auth, database and API modules in parallel using separate subagents.” * Chain: “Use code-reviewer to find performance issues, then optimizer to fix them.” * Read-only DB analyst: tools: Bash + PreToolUse hook that exits 2 on INSERT/UPDATE/DELETE/DROP.
===== 10. Parallel sessions ===== * Worktrees: claude -w feature-auth starts a session in a new git worktree so parallel edits cannot collide. Desktop app runs several side by side; cloud sessions run them remotely. * Worktrees lack gitignored files: list small ones in .worktreeinclude (copied); large dirs via worktree.symlinkDirectories; or keep the install command in CLAUDE.md. * Cleanup: unnamed clean worktrees removed on exit; named/dirty ones ask; leftovers swept after cleanupPeriodDays. claude -p --worktree runs: remove manually (git worktree remove <path>). * /batch <change>: splits a mechanical change into 5–30 units, shows the plan, runs each in its own worktree, opens one PR each. * Background sessions: /bg sends the current session to the background; claude --bg <task> starts one detached; claude agents (research preview) shows everything running locally. * Agent teams: coordinated teammate sessions the main session spawns and supervises (separate feature). * Cheap independent review: a second session that did not watch the code being written reviews @file; paste findings back.
===== 11. Headless and scripting =====claude -p "prompt" runs once and exits — CI jobs, git hooks, shell loops.^ Flag ^ Purpose ^| --bare | skip hooks, skills, plugins, MCP, all CLAUDE.md; auth from ANTHROPIC_API_KEY or --settings helper. Reproducible anywhere || --append-system-prompt, --mcp-config, --settings | supply exactly what the run needs || --allowedTools "..." | pre-approve tools || --permission-mode dontAsk | refuse everything else (or auto for classifier review) || --max-turns N, --max-budget-usd X | hard stops || --output-format json / stream-json --verbose | parseable result / live events || --no-session-persistence | no transcript written || --setting-sources user | ignore project settings/MCP in untrusted repos |
for file in $(cat files.txt); do claude --bare -p "Migrate $file to the new logger API and commit. Reply OK or FAIL." \ --allowedTools "Read,Edit,Bash(git add *),Bash(git commit *)" \ --permission-mode dontAsk \ --max-turns 20done
* Run on 3 files first, inspect failures, fix the prompt, then run the rest. * claude -p "/goal <condition>" runs a goal loop to completion. * Pipe input: git diff main --name-only | claude -p "review these changed files for security issues". * CI integrations: GitHub Actions, GitLab CI/CD, GitHub Code Review; Agent SDK for custom orchestration.
===== 12. Scheduling =====The agent can carry work to completion; something else must start it.^ ^ Cloud scheduled task ^ Desktop scheduled task ^ /loop ^| Runs on | Anthropic cloud | your machine | your machine || Machine must be on | no | yes | yes || Open session needed | no | no | yes || Survives restart | yes | yes | restored on --resume (with exceptions) || Local files | no (fresh clone) | yes | yes || Permissions | auto mode by default | per task | inherits session || Min interval | 1 hour | 1 min (Claude-set) | 1 min || Create | /schedule, web, Desktop | Desktop app | /loop |
==== 12.1 /loop ==== * /loop 5m check the deploy — fixed interval (s/m/h/d; rounded to cron steps). * /loop check CI and address review comments — self-paced: agent picks 1 min–1 h each iteration and prints why. * /loop alone — built-in maintenance prompt: continue unfinished work → tend the branch's PR (comments, CI, conflicts) → cleanup passes. No new initiatives; irreversible actions only if already authorised. * Replace the default with .claude/loop.md (project) or ~/.claude/loop.md (user); edits apply next iteration; max 25,000 bytes. * Skills as prompts: /loop 20m /review-pr 1234 (only model-invocable skills run). * Stop: Esc (self-paced); ask the agent to cancel (fixed). One-shots: “remind me at 3pm to push the release branch”. * Underlying tools: CronCreate, CronList, CronDelete; max 50 tasks/session; local timezone. * Limits: fires only while the session is running and idle; recurring tasks expire after 7 days; no catch-up for missed fires; jitter: recurring tasks start up to half the interval late (max 30 min; */5 runs 15 s early instead); one-shots at :00/:30 can fire up to 90 s early — schedule off the hour when timing matters. * Event-driven alternative: Channels push CI failures into a session instead of polling. CLAUDE_CODE_DISABLE_CRON=1 disables scheduling.
==== 12.2 Cloud scheduled tasks ==== * /schedule in the CLI (claude.ai login required), or claude.ai/code/routines. Triggers: timer, GitHub events, API. * Each run = fresh session, fresh clone; personal ~/.claude/skills not available. * Protect main with a branch rule the task cannot bypass, and watch the first runs before trusting it.
===== 13. Unattended-run checklist ===== - Done defined? Goal condition, spec file, or failing test to turn green. (3) - Self-check? Tests, Stop hook, review step. (3, 4) - Fenced? Permission rules, dontAsk, sandbox, worktree, the one branch it may push. (8, 10) - Stops? --max-turns, --max-budget-usd, spend limit. (11) - Result and sign-off? PR, comment or summary; a human approves merges, deploys, anything irreversible.
===== 14. Quick reference =====^ Command / flag ^ Does ^| /init | draft CLAUDE.md || /memory | open instruction files and memory; toggle auto memory || /context | what loaded and what uses context || /usage | token/usage breakdown || /doctor, /doctor prompt-audit | setup checkup; instruction audit || /effort, /model | thinking level; model || /permissions | rules, recently denied, auto-mode rules || /sandbox | enable/configure sandbox || /hooks | browse hooks || /skills, /skill-doctor, /reload-skills | manage skills || /agents | (now) reminder to edit .claude/agents/ || /tasks | running subagents/background work || /goal, /loop, /schedule | completion loop; interval loop; cloud task || /code-review, /verify, /run, /batch | review; run-and-check; launch; parallel PRs || /subtask, /bg, /btw | fork; background session; side question || /rewind, /clear, /compact, /rename | roll back; reset; summarise; name session || /add-dir, /cd, /config, /mcp, /plugin | dirs; move session; settings; MCP; plugins || claude -c / --resume <n> | continue latest / resume named || claude -w <n> | session in a worktree || claude -p (+ --bare etc.) | headless || claude --agent <n> | run session as a subagent || claude agents | background session dashboard || claude purge <path> | delete a project's local data || Shift+Tab, Esc, Esc Esc, Ctrl+O, Ctrl+G | cycle modes; stop; rewind menu; transcript; edit plan |
===== 15. Sources ===== * Best practices * /goal * Hooks reference · Hooks guide * The .claude directory · Memory * Skills * Permissions · Permission modes * Subagents · Scheduled tasks * Changelog * Inspiration: Simon Scrapes, “How the Top 1% Use Claude Code Differently” (10 Oct 2026) — chapter titles only; claims there (e.g. “no skill beats skill 7/9 times”) are unverified.
