Mastering Claude Code CLI: The Complete Guide for DevOps Engineers
If you have been using Claude in a browser tab to help with code, you are leaving most of its capability on the table. Claude Code CLI brings the full power of Claude directly into your terminal — it reads your actual codebase, runs real commands, edits files, commits code, and integrates with every tool in your DevOps stack. This guide covers everything from installation to advanced patterns that most engineers never discover.
What Is Claude Code?
Claude Code is an agentic coding assistant that lives in your terminal, IDE, or browser. Unlike a chat interface where you paste code snippets, Claude Code:
- Reads your entire codebase — it understands the real structure of your project
- Runs actual commands —
git,docker,kubectl,terraform,npm, whatever you need - Edits files directly — makes changes across multiple files in a single operation
- Integrates with your IDE — VS Code and JetBrains show diffs in their native viewers
- Connects to external tools — databases, GitHub, AWS, Slack, and more via MCP
The key difference from a coding chatbot: Claude Code is not a passive assistant waiting for your next message. It is an active participant that takes actions, checks results, and iterates. AI can write code — but Claude Code can also follow your rules, protect your codebase, automate your workflows, and work as part of a team.
For DevOps engineers specifically, this means you can say “review our Terraform configs for security issues, fix what you find, and open a PR” — and it will actually do it.
Installation
macOS / Linux:
curl -fsSL https://claude.ai/install.sh | bash
Homebrew:
brew install --cask claude-code
Windows (PowerShell):
irm https://claude.ai/install.ps1 | iex
After installing, run claude in any project directory to start a session. Run claude --help to see all options.
Quick start:
cd my-project
claude # interactive session
claude "Fix the login bug" # start with a specific task
claude -p "explain this project structure" # one-off query and exit
claude --model opus # start with a specific model
claude -c # continue your last session
Three Ways to Talk to Claude Code
Claude Code has three distinct types of input — knowing which to use saves time:
| Type | When | Examples |
|---|---|---|
| CLI Commands | Before starting a session (in your terminal) | claude, claude -p "query", claude --model opus |
| Slash Commands | During a session (inside the REPL) | /clear, /compact, /model, /memory |
| Special Notations | Shortcuts while typing a prompt | @file.ts, !git status, # note |
Special Notations at a Glance
| Notation | What it does |
|---|---|
@src/main.py | Reference a specific file — Claude reads it immediately |
!git status | Run a shell command directly without Claude’s conversational processing |
# remember this | Add a quick note to Claude’s memory for this session |
The ! prefix (Bash Mode) is particularly useful: prefix any input with ! to run a shell command straight to your terminal, bypassing the LLM entirely. No tokens consumed. Tab autocomplete works for commands and paths:
> !pwd
> !npm run test
> !ls -la
Claude Code Modes
Think of modes like gears in a car — you shift them based on the road. Each mode gives Claude a different level of freedom to act on your code. Switch between them anytime with Shift+Tab:
Default Mode → Auto-Accept Mode → Plan Mode → (back to Default)
| Mode | What Claude can do | Best for |
|---|---|---|
| Default | Asks permission before every change | Careful, step-by-step work; production code; new to Claude Code |
| Auto-Accept | Edits files without asking | Fast, repetitive tasks; cleanup; following a well-defined plan |
| Plan | Read-only — cannot change anything | Research, planning, exploring before committing |
The current mode is always visible at the bottom of the terminal.
Default Mode — The Safe Driver
This is the standard mode you start with. Claude asks for your confirmation before editing any file or running any command. Think of it as a co-pilot who always checks with you before taking the wheel:
Claude proposes a change → You review it → You approve or reject → Claude executes
Use Default Mode when working on production code, when you are new to Claude Code, or when dealing with sensitive files and configurations.
Auto-Accept Mode — The Fast Lane
Claude automatically applies file edits without waiting for your approval. The terminal shows “auto-accept edit on” when active.
Safety tip: Always commit your work before entering Auto-Accept Mode. If anything goes wrong, you can easily revert with git checkout.
Use it for: repetitive refactoring across multiple files, code cleanup tasks, following a plan you have already reviewed.
Plan Mode — The Architect
Claude enters a read-only state — it can look at your code but cannot change anything. Think of it as “Architect Mode”: observe, analyse, plan, but never execute.
What Claude CAN do in Plan Mode:
- Read files and analyse code
- Search through your codebase
- Understand project structure and dependencies
- Build implementation strategies
- Ask you clarifying questions
What Claude CANNOT do in Plan Mode:
- Edit or create files
- Run Bash commands
- Install packages
- Make any modifications whatsoever
The recommended workflow:
- Enter Plan Mode (Shift+Tab twice) — give your instruction: “I want to add OAuth2 authentication. Create a detailed plan.”
- Review and refine — ask follow-up questions until the plan looks right
- Switch to Default or Auto-Accept — press Shift+Tab, say “Now implement this plan.”
Why this matters: Planning consumes fewer tokens than execution. Do your thinking in Plan Mode, then execute efficiently.
CLAUDE.md — Your Project’s Permanent Memory
Every time you start a Claude Code session, it reads CLAUDE.md files automatically. Think of it as a briefing document — you write it once and never have to re-explain your project setup.
Where to put them
| File | Scope | Shared via Git? |
|---|---|---|
~/.claude/CLAUDE.md | All your projects | No — personal preferences |
./CLAUDE.md | This project | Yes — team-wide conventions |
./.claude/CLAUDE.md | This project (alt) | Yes |
./CLAUDE.local.md | This project | No — gitignored overrides |
What to put in a project CLAUDE.md
The golden rule: include what Claude cannot infer from reading the code. Commands, gotchas, team conventions, and architecture decisions that are not obvious from the files.
# My Infrastructure Platform
## Build and Test
- Build: `npm run build`
- Tests: `npm test` — run single tests with `npm test -- --grep "auth"`
- Lint: `npm run lint`
- Type check: `npm run typecheck`
## Architecture
- API handlers in `src/api/handlers/`
- Terraform configs in `infra/`
- Each service has its own `Dockerfile.prod`
## Code Style
- ES modules only (import/export) — no CommonJS
- 2-space indentation
- camelCase for variables, PascalCase for types
## Git Workflow
- Feature branches: `feature/description`
- Always create a PR — never push directly to main
## Common Commands
- Deploy staging: `npm run deploy:staging`
- Deploy prod: `npm run deploy:prod`
- View production logs: `npm run logs:prod`
- Run migrations: `npm run db:migrate`
## Secrets
- Never hardcode credentials — all secrets in AWS Secrets Manager
- Use `.env.example` for documentation, never `.env` itself
## Known Gotchas
- The auth service requires `NODE_ENV=production` to initialise properly
- Database migrations run automatically on deploy — no manual step needed
- Some integration tests require a local Redis instance on port 6379
Path-scoped rules
For large projects, create .claude/rules/ with topic-specific files that only load when Claude is working in the relevant area:
.claude/
├── CLAUDE.md ← always loaded
└── rules/
├── api.md ← loads when editing src/api/**
├── security.md ← loads when editing any auth-related file
└── infra.md ← loads when editing infra/**
Example .claude/rules/security.md:
---
paths:
- "src/api/**/*.ts"
- "infra/**/*.tf"
---
# Security Rules
- Always validate and sanitise user input at API boundaries
- Use parameterised queries — never string interpolation in SQL
- Never log secrets, tokens, or PII — scrub before logging
- Return generic error messages externally — no stack traces
- Require authentication on all non-public endpoints
Keep CLAUDE.md under 200 lines. Longer files reduce adherence — Claude loses track of rules buried at line 350.
Saving Tokens — How to Keep Costs Low
Context is the most important resource to manage. Every message you send includes your entire conversation history, all the files Claude has read, and every command output. It adds up fast.
Check your usage
/cost # estimated session cost
/usage # detailed token breakdown
/context # see what is consuming context space
Clear between tasks
The single most effective thing you can do:
/clear
When you finish a task and start something unrelated, clear the context. Stale conversation history about your auth bug wastes tokens on every message when you switch to asking about your CI pipeline.
Compact your context
/compact focus on infrastructure changes
/compact summarises the conversation history but lets you tell it what to preserve. Use it when a session gets long but you are not ready to clear completely.
Add a compact instruction to your CLAUDE.md:
## Compact instructions
When compacting, always preserve:
- Code changes made so far
- Test results and error messages
- Architecture decisions reached
Choose the right model for the task
/model claude-sonnet-4-6 # default — best balance of cost and capability
/model claude-opus-4-7 # for complex architectural decisions
/model claude-haiku-4-5 # for simple repetitive tasks
Sonnet handles 95% of DevOps tasks well. Save Opus 4.7 for genuinely complex problems — architecture decisions, security audits, and long agentic pipelines where reasoning depth matters.
Control extended thinking
Extended thinking is powerful but expensive. Turn it down for simple tasks:
/effort low # minimal thinking — fast and cheap
/effort medium # moderate reasoning
/effort high # default — thinks when it helps
/effort max # maximum thinking — best answer on hard problems
Use subagents for investigation
When you need Claude to explore a large codebase to answer a question, spawn a subagent instead of doing it in your main session:
Use a subagent to investigate why our authentication service is slow
Subagents run in their own context and report back a summary — keeping your main conversation clean.
MCP — Connecting Claude to Everything
MCP (Model Context Protocol) is what lets Claude Code talk to external systems — databases, GitHub, AWS, Slack, your custom APIs. Once configured, Claude can query them directly without you having to copy-paste data.
Adding MCP servers
# Add a GitHub MCP server
claude mcp add --transport http github https://api.github.com/mcp/ \
--header "Authorization: Bearer YOUR_GITHUB_PAT"
# Add a local Postgres server
claude mcp add --transport stdio postgres \
"mcp-postgres --connection-string postgresql://user:pass@localhost/db"
Or configure directly in .claude/settings.json:
{
"mcp": {
"servers": {
"github": {
"transport": "http",
"url": "https://api.github.com/mcp/",
"headers": {
"Authorization": "Bearer YOUR_GITHUB_PAT"
}
},
"postgres": {
"transport": "stdio",
"command": "mcp-postgres",
"args": ["--connection-string", "postgresql://user:pass@localhost/db"]
}
}
}
}
Useful MCP servers for DevOps
| Server | What it enables |
|---|---|
| GitHub | Search PRs, read comments, create issues, review code diffs |
| Postgres / MySQL | Query databases directly, analyse schemas, debug data issues |
| AWS | List resources, check CloudWatch logs, manage S3 |
| Web Fetch | Pull in documentation, error pages, API references |
| Filesystem | Read files outside your project root |
| Slack | Post notifications, read channel history |
| Memory | Persist information across sessions |
| Docker | Inspect containers, images, network config |
Check what is loaded
/mcp # list configured servers and their context cost
Disable servers you are not using — each one adds to your context overhead.
How MCP Manages Your Context Window
A common concern: “If I connect 10 MCP servers with 90 tools, won’t that blow up my context?” The answer is no — MCP uses progressive loading.
At session start Claude fetches only the tool names from all connected servers, not the full schemas. Think chapter titles, not chapters. The complete JSON schema for a tool only loads when Claude actually needs it to handle your prompt.
Example: You have 10 MCP servers, 90 tools total.
- Your prompt says: “Check if the database connection is working”
- Claude scans the lightweight name list, identifies the Postgres tool
- Loads only that tool’s full schema
- All other 89 tools stay as one-line name references
Result: ~95% less context consumption compared to loading all schemas upfront. You can connect a large number of MCP servers without meaningfully affecting your available context.
Parallel MCP reconnection (May 2026)
When Claude Code re-initialises MCP servers — during subagent startup or SDK reconfiguration — servers now connect in parallel rather than serially. If you have six MCP servers configured, startup time drops from the sum of six serial connections to roughly the longest single connection. For setups with many MCP servers, this meaningfully reduces session startup latency.
Hooks — Automating the Boring Parts
Hooks are shell commands that run automatically at specific points in Claude’s lifecycle. Unlike CLAUDE.md instructions (which are advisory), hooks are deterministic — they always run.
Hook events
| Event | When it fires |
|---|---|
SessionStart | At the beginning of every session |
UserPromptSubmit | When you submit a prompt, before Claude begins processing — good for input sanitisation |
PreToolUse | Before Claude runs any tool (can block the tool from running) |
PermissionRequest | When Claude displays a permission request dialog |
PostToolUse | After a tool succeeds — includes duration_ms (tool execution time) |
PostToolUseFailure | After a tool fails — also includes duration_ms |
Notification | When Claude Code sends a notification to the user |
SubagentStart | When a subagent is created |
SubagentStop | When a subagent completes its task |
Stop | When Claude finishes generating its response |
TeammateIdle | When an agent team member is about to become idle |
TaskCompleted | When a task is marked completed |
ConfigChange | When a config file is modified during the session |
WorktreeCreate | When a Git worktree is created via --worktree or isolation settings |
WorktreeRemove | When a worktree is removed (session ends or subagent finishes) |
PreCompact | Before Claude performs context compaction |
SessionEnd | When the session closes |
Execution behaviour: All hooks matching the same event run in parallel, not sequentially. If multiple hooks contain the identical command, Claude Code automatically deduplicates — the command runs only once.
Creating hooks interactively: Type /hooks inside any session to open an interactive menu. You can add, configure, and delete hooks without editing JSON manually.
Choosing a Hook Language
Hooks run synchronously — Claude waits for them to finish before continuing. For high-frequency events like PreToolUse and PostToolUse, startup time accumulates fast:
| Language | Startup time | Best for |
|---|---|---|
| Bash | ~10–20ms | Simple tasks — string checks, file guards, quick env loads |
| Node.js | ~50–100ms | High-frequency hooks (PreToolUse, PostToolUse) — worth the tradeoff for logic-heavy hooks |
| Python | ~200–400ms | Less frequent hooks (SessionStart, SessionEnd) — or during debugging/exploration |
A hook that takes 300ms on every PostToolUse call adds up to minutes of dead time in a long session. Use Bash or Node for anything that runs often; save Python for hooks that fire once.
Configuration
Hooks go in .claude/settings.json:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit",
"hooks": [
{
"type": "command",
"command": "~/.claude/hooks/format-on-save.sh"
}
]
}
]
}
}
Practical hook examples
Auto-format files after Claude edits them:
#!/bin/bash
# ~/.claude/hooks/format-on-save.sh
input=$(cat)
files=$(echo "$input" | jq -r '.tool_output.files_edited[]' 2>/dev/null)
for file in $files; do
case "$file" in
*.ts|*.js) npx prettier --write "$file" 2>/dev/null ;;
*.py) black "$file" 2>/dev/null ;;
*.go) gofmt -w "$file" 2>/dev/null ;;
*.tf) terraform fmt "$file" 2>/dev/null ;;
esac
done
exit 0
Block destructive commands:
#!/bin/bash
# ~/.claude/hooks/block-destructive.sh
input=$(cat)
cmd=$(echo "$input" | jq -r '.tool_input.command')
BLOCKED="rm -rf|kubectl delete|terraform destroy|DROP TABLE|truncate"
if echo "$cmd" | grep -qE "$BLOCKED"; then
jq -n '{
hookSpecificOutput: {
hookEventName: "PreToolUse",
permissionDecision: "deny",
permissionDecisionReason: "Destructive command blocked by hook. Review and run manually."
}
}'
else
exit 0
fi
Load environment variables at session start:
{
"env": {
"NODE_ENV": "development",
"DEBUG": "app:*",
"POSTGRES_HOST": "localhost",
"AWS_REGION": "us-east-1"
}
}
Or use a SessionStart hook to load from a .envrc:
#!/bin/bash
# ~/.claude/hooks/load-env.sh
[ -f .envrc ] && source .envrc
exit 0
Permissions — Fewer Prompts, More Flow
By default, Claude asks for permission before running commands or editing files. Here is how to reduce that friction without giving up safety.
The Three Permission Guards
Every permission in Claude Code falls into one of three categories — Allow, Ask, or Deny:
- Allow — Claude can do this without prompting you
- Ask — Claude pauses and asks for confirmation before proceeding
- Deny — Claude cannot do this, period
These map directly to the allow and deny arrays in settings, with the default being Ask for anything not listed.
Permission modes
Press Shift+Tab to cycle through Default → Auto-Accept → Plan modes. You can also set a mode at launch without changing persistent settings:
claude --permission-mode acceptEdits # fast lane for this session only
claude --permission-mode bypassPermissions # skip all prompts (containers/VMs only)
All five modes:
| Mode | Behaviour | When to use |
|---|---|---|
default | Asks permission on first use of each tool | Daily work, careful changes |
acceptEdits | Auto-approves all file edits for the session | Repetitive refactoring, cleanup |
plan | Can read/analyse but cannot modify anything | Research, planning phase |
dontAsk | Denies everything unless explicitly pre-approved | Locked-down environments |
bypassPermissions | Skips all prompts | Containers/VMs only — dangerous on local |
Or set a persistent default in .claude/settings.json:
{
"permissions": {
"defaultMode": "acceptEdits"
}
}
Settings scopes hierarchy
Settings cascade through five levels — more specific always wins:
| Scope | File | Who controls it |
|---|---|---|
| Managed (highest) | managed-settings.json in Claude Code install | System admin — cannot be overridden by anyone |
| CLI Args | Session flags only | You, per session |
| Local | .claude/settings.local.json | You, per project (gitignored) |
| Project | .claude/settings.json | Team, committed to git |
| User (lowest) | ~/.claude/settings.json | You, global defaults |
If a permission is allowed in your user settings but blocked in the project settings, the project rule wins — it is more specific.
Use the /status command to see exactly which layer is controlling any setting and debug unexpected behaviour.
Company-wide announcements
Enterprise teams can broadcast rules to every Claude session by adding companyAnnouncements to the managed settings:
{
"companyAnnouncements": [
"Never commit secrets, tokens, or credentials to the repository.",
"All production changes require a PR — never push directly to main.",
"Write meaningful commit messages — future teammates will thank you."
]
}
These strings are shown to Claude at session start, regardless of what project CLAUDE.md says.
Allowlist common operations
Stop being asked about things you always approve:
{
"permissions": {
"allow": [
"Bash(npm run *)",
"Bash(git add *)",
"Bash(git commit *)",
"Bash(git status)",
"Bash(git diff *)",
"Bash(docker build *)",
"Bash(docker ps)",
"Bash(kubectl get *)",
"Bash(terraform plan *)",
"Bash(terraform init)",
"Bash(terraform fmt *)",
"Edit",
"WebFetch(domain:github.com)",
"WebFetch(domain:docs.aws.amazon.com)"
],
"deny": [
"Bash(terraform apply)",
"Bash(terraform destroy *)",
"Bash(kubectl delete *)",
"Bash(rm -rf *)",
"Read(.env)"
]
}
}
Separate team and personal settings
Put shared permissions in .claude/settings.json (committed to git) and personal overrides in .claude/settings.local.json (gitignored):
// .claude/settings.local.json (your personal overrides)
{
"permissions": {
"allow": [
"Bash(brew *)",
"Bash(nvim *)"
]
}
}
Essential Slash Commands
Session & context:
| Command | What it does |
|---|---|
/clear | Reset conversation history — do this between tasks |
/compact [focus] | Summarise history, optionally preserving specific areas |
/cost | Show estimated session cost |
/usage | Detailed token usage breakdown |
/context | Show what is taking up context space |
/rename [name] | Name the current session for easy resumption |
/resume [name] | Resume a named session |
/rewind | Open checkpoint menu (double-tap Esc also works) |
/btw [question] | Ask a quick side question that never enters history |
Configuration & settings:
| Command | What it does |
|---|---|
/config | Open interactive settings UI — one-stop shop for all Claude Code settings |
/status | Show all active settings and which layer (managed/project/user) controls each |
/permissions | Interactive UI for managing allow/deny/ask rules in real time, no restart needed |
/output-style | Switch response style: Default / Explanatory / Learning |
/voice | Push-to-talk dictation — hold Space, speak, release |
Models & tools:
| Command | What it does |
|---|---|
/model [name] | Switch Claude model mid-session |
/effort [low|high|xhigh] | Control extended thinking |
/mcp | Manage and check MCP servers |
/add-dir [path] | Add an additional directory to Claude’s working scope |
Project & memory:
| Command | What it does |
|---|---|
/init | Generate a starter CLAUDE.md for the current project |
/memory | View and edit CLAUDE.md and auto memory |
/hooks | View configured hooks |
Code quality:
| Command | What it does |
|---|---|
/review | Run a code review subagent |
/ultrareview | Multi-agent cloud review — finds and verifies real bugs before you merge (costs $5–$20 per run) |
/statusline | Generate a status bar script and configure it automatically |
/doctor | Diagnose installation issues |
The Desktop App
Alongside the CLI, Claude Code has a redesigned desktop application (Mac and Windows) that adds capabilities the terminal interface cannot match:
- Session sidebar — all your open and recent sessions visible at a glance; switch between them without losing context
- Drag-and-drop workspace — drag files and images directly into the conversation
- Integrated terminal and file editor — edit files and run commands without switching windows
- Faster diffs — file change proposals render immediately with improved performance
- Expanded previews — see rendered HTML, SVG, and markdown output inline
- Parallel task panel — run multiple independent tasks simultaneously and monitor each
The desktop app runs the same underlying model and tools as the CLI. It is particularly useful for visual tasks (computer use, screenshot analysis, design review) and for engineers who prefer not working in a terminal.
Download it from claude.ai/download. The CLI and desktop app share session history and CLAUDE.md files.
IDE Integration
VS Code
Install the Claude Code extension from the marketplace, or:
code --install-extension anthropic.claude-code
Useful keyboard shortcuts:
| Action | Shortcut |
|---|---|
| Focus Claude input | Cmd+Esc |
| Insert file reference | Option+K |
| New conversation | Cmd+N |
| Open in new tab | Cmd+Shift+Esc |
When Claude proposes file changes, VS Code shows them in its native diff viewer — you can approve, reject, or edit each change individually before accepting.
JetBrains (IntelliJ, PyCharm, GoLand, WebStorm)
Install Claude Code from Settings → Plugins → Marketplace.
Connect your terminal session to the IDE:
claude
/ide
This links the terminal session to your open IDE so diffs appear there instead of in the terminal.
Sessions, Context & Checkpoints
The Context Window
Every Claude Code session has a finite context window — the “invisible fuel tank.” Here is how the 1 million token window is distributed:
| Component | Approximate size |
|---|---|
| System prompt (Claude Code instructions) | ~100K tokens |
| Conversation history | ~400K tokens |
| Tool call results | ~50K tokens |
| Skills (loaded on demand) | ~50K tokens |
| Available to work | ~400K tokens |
When context fills up, Claude first removes older tool outputs, then summarises parts of the conversation. Use /context to see exactly what is consuming space.
/cost # estimated session cost
/context # see what is consuming context space
/compact focus on infrastructure changes # summarise history, preserve what matters
/clear # reset entirely — do this between unrelated tasks
Advanced pattern for very long tasks: have Claude write its progress into a .md file, run /clear to start completely fresh, then tell Claude to read that file. You get preserved knowledge with a clean context.
Sessions Are Directory-Scoped, Not Branch-Scoped
Each Claude Code session is tied to your current directory, not to a git branch. When you switch branches, the same session continues — Claude reads files from the newly checked-out branch, but the conversation history stays unchanged.
This means Claude still remembers everything you discussed, even though the underlying files are now different. If you need separate Claude sessions per branch, use git worktrees — they create separate folders, and each folder gets its own independent Claude session.
Resuming and Forking Sessions
Resume your last session or a named one:
claude -c # resume most recent session
claude --resume auth-implementation # resume by name
When you resume, you get the full conversation history back. Session-scoped permissions reset — you will need to re-approve them, like access badges expiring when you reopen the building.
Fork a session to try a different approach without losing the original:
claude --continue --fork-session
This copies the entire conversation history into a new session. The original stays untouched. It is like photocopying your notebook and trying different approaches on the copy.
| Resume | Fork | |
|---|---|---|
| Session ID | Same | New |
| Behaviour | Continues from where you left off | Copies history, branches off |
| Original session | Gets new messages added | Stays unchanged |
| Use when | Continuing the same work | Experimenting with a different approach |
Smart Session Habits
These five habits separate engineers who get consistent results from those who fight Claude:
1. Clear Between Tasks
Run /clear after finishing one task before starting the next. Bug-fixing conversations pollute feature work — every leftover token is wasted context and a potential source of confusion.
2. Compact at Natural Breakpoints
Don’t wait for autocompact to kick in at 80–85% context usage. Run /compact when you decide — after finishing a subtask, before starting a new phase. Add a focus instruction so Claude knows what to preserve:
/compact Keep only the test results and the current implementation plan
3. Name Your Sessions
Type /rename payment-gateway-fix as soon as you start meaningful work. Future you will thank present you when staring at a list of 50 unnamed sessions and trying to find the right one to resume.
4. Monitor Your Context
Run /context periodically — think of it as checking your fuel gauge. If you are above 60% and still have significant work ahead, compact or clear. The status line can show context percentage at all times so you never have to ask.
5. The Document & Clear Pattern
For very large tasks that would fill the entire context window: ask Claude to write its plan and progress into a .md file, then run /clear and start a fresh session telling Claude to read that file and continue. You get a clean context window with fully preserved knowledge.
Forking Sessions with Worktrees
For parallel work on multiple branches simultaneously, use the --worktree flag (or its shorthand -w):
claude --worktree feature-auth # creates worktree + branch, opens isolated session
claude --worktree bugfix-api # second independent session
If you omit the name, Claude generates a random one. What happens under the hood:
- A new folder is created at
<repo>/.claude/worktrees/<name> - A new branch is created automatically:
worktree-<name> - Claude opens inside that isolated workspace with its own session
Each worktree has its own files and its own branch, but shares the same Git history and remote. Parallel edits never conflict.
Creating a worktree mid-session — you don’t need to restart. Just say:
- “Start a worktree”
- “Work in a worktree”
Claude creates one automatically and moves your work into it.
Checkpoints: Ctrl+Z on Steroids
Every prompt you submit triggers a silent snapshot of your code state before Claude touches anything. These checkpoints are automatic — you do not press a save button. They persist across sessions (you can close the terminal and still rewind later) and expire after 30 days.
Open the checkpoint menu by double-tapping Esc or running /rewind. You see a list of checkpoints — pick one and choose how to restore:
| Option | What it does |
|---|---|
| Restore Code Only | Reverts file changes, keeps the conversation — good when code went wrong but context is still useful |
| Restore Conversation Only | Rewinds the chat, keeps the code — good when you want to re-prompt differently without changing files |
| Restore Both | Full reset — code and conversation go back together |
| Summarize from here | Condenses messages from that checkpoint forward without restoring anything — surgical alternative to /compact |
What checkpoints do NOT track:
- Files modified by bash commands (
rm,mv, shell scripts) — only Claude’s direct Edit/Write tool calls are captured - Manual changes you made in your own editor outside Claude
- After 30 days — use Git for permanent history
Best practice: checkpoints cover the session; Git covers everything else. Before any large task, commit first:
git checkout -b feature/refactor-auth
git add . && git commit -m "before AI refactor"
If everything breaks, git reset --hard brings you back instantly.
Claude Code + GitHub
Claude Code integrates with GitHub at three levels — pick the right one for your workflow:
| Level | What it means | Best for |
|---|---|---|
| Terminal | Run Claude locally with gh CLI and GitHub MCP | Pair programming, daily dev work |
| GitHub Actions (@claude bot) | Tag @claude on any issue or PR comment; bot runs Claude automatically | Code review, bug fixes, async team workflows |
| Headless / Scripting | claude -p "..." flag in CI/CD pipelines, cron jobs, scripts | Automated code review, nightly audits |
Natural Language Git Commands
The fastest way to do git work is to just describe it:
# Instead of memorising git commands:
"commit and push with a descriptive message"
"create a feature branch called feature/auth-refresh and switch to it"
"push this branch and create a PR with a proper description"
"look at issue #42 and fix it"
"stage only the test files and commit them separately"
Claude translates these into actual git and gh commands, runs them, and reports back. It reads your diff, writes a meaningful commit message, and handles the mechanics.
How Claude Creates a PR (Behind the Scenes)
When you ask Claude to open a PR, here is the 4-step sequence it runs automatically:
- Gather context — runs
git status,git diff,git log, andgit diff main..HEADto understand every change - Prepare the branch — checks that you are on a feature branch (creates one if needed) and pushes to remote
- Analyse changes — reads the diff, identifies the purpose of each change, groups related changes
- Create the PR — runs
gh pr createwith a generated title, structured description (summary + details + test plan), and appropriate labels
The result is a PR that reads like a human wrote it — because it is based on actual understanding of the change, not just the commit message.
commit-commands Plugin
The commit-commands plugin adds three high-signal commands:
| Command | What it does |
|---|---|
/commit | Stages changed files and writes a smart commit message based on the diff |
/commit-push-pr | Commits, pushes the branch, and opens a PR — all in one step |
/clean_gone | Removes local branches that have been deleted on the remote (post-merge cleanup) |
Install the plugin once and use these commands across every project.
Automated PR Creation
After making changes, instead of switching to GitHub:
claude "create a PR for these changes with a detailed description"
Claude runs the full 4-step sequence above and opens the PR with description, test plan, and reviewers if you have them configured.
Pipe GitHub Data Directly
# Review a PR diff
gh pr diff 42 | claude -p "review this PR for bugs, security issues, and best practices"
# Summarise recent issues
gh issue list --limit 20 | claude -p "what are the most common pain points here?"
# Check failed CI runs
gh run list --status failure --limit 5 | claude -p "what patterns do you see in these failures?"
Setting Up the @claude Bot
The fastest path is a single slash command:
/install-github-app
What it does step by step:
- Installs the Claude GitHub App from
github.com/apps/claudeto your repo - Creates a PR containing
.github/workflows/claude.yml - Before merging that PR, add
ANTHROPIC_API_KEYas a GitHub Secret: Settings → Secrets and variables → Actions - Merge the PR — setup complete
Test it immediately: go to any PR or issue and type @claude review this PR or @claude fix this bug. The bot responds with comments, code changes, or a new PR — and shows real-time progress via visual checkboxes that update as it works.
The @claude Bot on GitHub Actions
Tag @claude in any issue comment or PR review, and the bot responds:
@claude please review this PR for security issues
@claude this test is failing — can you fix it and push the fix?
@claude look at issue #234 and implement the described feature
The bot runs Claude in a GitHub Actions environment, reads the full issue/PR context, and either comments with an analysis or opens a commit/PR with a fix. Useful for async team workflows where you want AI involvement without blocking your own terminal session.
CI/CD Integration (Headless Mode)
name: Claude Code Review
on: [pull_request]
jobs:
review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: AI Code Review
run: |
claude -p "Review the changes in this PR for bugs, security issues, and best practices. Be specific and include file:line references." \
--output-format json > review.json
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
The -p flag runs Claude non-interactively — perfect for CI. Combine with --output-format json for structured output you can parse downstream.
DevOps-Specific Workflows
Terraform
# Review configs for issues
claude "review infra/main.tf for security issues and best practices"
# Plan changes safely
claude "run terraform plan and explain what would change"
# Generate module documentation
claude "generate README documentation for our terraform modules"
Restrict permissions so Claude can plan but never apply:
{
"permissions": {
"allow": ["Bash(terraform plan *)", "Bash(terraform init)", "Bash(terraform fmt *)"],
"deny": ["Bash(terraform apply)", "Bash(terraform destroy *)"]
}
}
Kubernetes
# Review manifests
claude "review all manifests in k8s/ for security and best practices"
# Generate a Helm chart
claude "create a Helm chart for our Node.js API service"
# Debug a failing deployment
cat deployment-error.log | claude -p "what is causing this failure and how do I fix it?"
CI/CD with GitHub Actions
name: Claude Code Review
on: [pull_request]
jobs:
review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: AI Code Review
run: |
claude -p "Review the changes in this PR for bugs, security issues, and best practices. Be specific." \
--output-format json > review.json
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
Pipe data directly
# Debug log output
cat app.log | claude -p "what errors are here and what is causing them?"
# Review recent git history
git log -20 --oneline | claude -p "summarise what changed recently"
# Analyse docker logs
docker logs myapp --tail 100 | claude -p "what is wrong with this service?"
Voice Dictation
Claude Code has a built-in voice interface — no third-party app required.
How to use:
- Press
/voiceto start a voice session - Hold Space to record, release to submit
- Claude transcribes and responds in text
Important details:
- Cloud-powered (not on-device) — audio is sent to a transcription service
- Free — voice transcription does not consume your API tokens or add to session cost
- Requires a Claude.ai login (not just an API key)
- Not available with raw API keys, AWS Bedrock, or Google Vertex — only with the Claude.ai-connected CLI
Voice is particularly useful when your hands are busy (reviewing logs on one screen, talking through an approach) or when you think faster by speaking than typing.
Output Styles
Use /output-style to change how Claude structures its responses for the rest of the session:
| Style | What it does | Best for |
|---|---|---|
| Default | Concise, direct answers — just the result | Production work, experienced users |
| Explanatory | Adds “Insight” blocks after each section explaining why a choice was made | Code review, understanding unfamiliar patterns |
| Learning | Leaves TODO(human): markers where you should fill in the next step yourself | Actively learning, practising, onboarding |
Example prompt:
/output-style learning
This is a session-level setting — it resets when you start a new session. For permanent preference, use defaultOutputStyle in your user settings.
When to switch styles:
- Pair programming with a junior: Explanatory so they see the reasoning
- Debugging a new codebase: Explanatory to understand what Claude discovers
- Practising a new language: Learning so you write the next line yourself
- Getting things done fast: Default (or omit the command entirely)
Working Directories
By default, Claude works within the directory you launched it from. For monorepos, microservices, or any project where relevant files live outside that root, you need to add directories explicitly.
Three ways to add directories:
# 1. At launch (CLI flag)
claude --add-dir ../shared-lib ../api-service
# 2. Inside a session (slash command — no restart needed)
/add-dir ../frontend ../design-system
# 3. Permanently in settings (persists across sessions)
// .claude/settings.json
{
"additionalDirectories": [
"../shared-lib",
"../api-service",
"../docs"
]
}
Common use cases:
| Scenario | What to add |
|---|---|
| Monorepo with shared utilities | ../packages/utils, ../packages/types |
| Microservices (touching multiple) | ../auth-service, ../payment-service |
| Docs outside the repo | ../company-docs, ~/notes/project |
| Frontend + backend in separate repos | ../frontend from the backend directory |
Adding a directory lets Claude read and edit files there — same as if those files were in your working directory. Permissions apply equally.
Status Line
The status line is a real-time display in your shell prompt showing Claude’s current state. It is powered by a JSON pipeline: Claude emits a JSON blob after each interaction, a script reads it from stdin and formats it, and the output appears in your prompt.
JSON schema Claude emits:
{
"model": "claude-opus-4",
"contextPercentage": 23,
"estimatedCost": 0.042,
"gitDirectory": "/Users/you/project",
"currentBranch": "feature/auth"
}
Example bash script (~/.claude-statusline.sh):
#!/bin/bash
input=$(cat)
branch=$(echo "$input" | jq -r '.currentBranch // ""')
ctx=$(echo "$input" | jq -r '.contextPercentage // ""')
cost=$(echo "$input" | jq -r '.estimatedCost // ""')
echo "[$branch] ctx:${ctx}% \$${cost}"
Set up with one command:
/statusline
The /statusline command auto-generates this script and adds it to your shell config — you do not need to write it manually. After running it, open a new terminal and the status line appears automatically.
Useful for catching context creep before it becomes a problem: when contextPercentage climbs past 70%, it is time to /compact or /clear.
Tips Most Engineers Miss
1. Ask side questions without polluting context:
/btw what Node version does this project need?
The answer appears in an overlay and is never saved to history.
2. Pipe directly from the shell:
cat errors.log | claude -p "what is causing this?"
3. Use ! for quick shell commands inside a session:
> ! git log --oneline -5
> ! docker ps
4. Name your sessions:
claude -n "oauth-implementation"
# Later
claude --resume oauth-implementation
5. Use worktrees for parallel work:
# Two independent sessions, two branches
claude -w feature-auth # terminal 1
claude -w bugfix-api # terminal 2
Built-in git worktree support is now available in the CLI (previously desktop-only). Each claude -w <branch> session gets an isolated checkout — parallel edits never conflict. Add isolation: worktree to a subagent’s frontmatter to give each spawned subagent its own worktree too.
6. Set a cost limit:
claude -p "audit entire infrastructure" --max-budget-usd 2.00
7. Use --add-dir in monorepos:
claude --add-dir ../shared-lib ../api-service -p "refactor the shared auth code"
8. Double-tap Escape to rewind without typing /rewind.
9. Generate your CLAUDE.md automatically:
/init
Claude reads your project and generates a starter CLAUDE.md. Edit it from there.
10. Check what the auto-memory system saved:
/memory
Claude saves learnings across sessions automatically. This shows what it remembers about you and your project.
Putting It All Together: A Recommended Setup
Here is a practical starting point for a DevOps project:
.claude/settings.json (commit to git):
{
"permissions": {
"defaultMode": "acceptEdits",
"allow": [
"Bash(npm run *)",
"Bash(git add *)",
"Bash(git commit *)",
"Bash(git status)",
"Bash(git diff *)",
"Bash(git log *)",
"Bash(terraform plan *)",
"Bash(terraform init)",
"Bash(terraform fmt *)",
"Bash(docker build *)",
"Bash(docker ps)",
"Bash(kubectl get *)"
],
"deny": [
"Bash(terraform destroy *)",
"Bash(terraform apply)",
"Bash(kubectl delete *)",
"Bash(rm -rf *)",
"Read(.env)"
]
},
"hooks": {
"PostToolUse": [
{
"matcher": "Edit",
"hooks": [{ "type": "command", "command": ".claude/hooks/format.sh" }]
}
]
}
}
CLAUDE.md (commit to git):
# Project Name
## Build and Test
- Build: `npm run build`
- Test: `npm test`
- Lint: `npm run lint`
## Deployment
- Staging: `npm run deploy:staging`
- Production requires manual approval — create a PR
## Architecture
- API: `src/api/` — Express + TypeScript
- Infra: `infra/` — Terraform on AWS
- K8s manifests: `k8s/`
## Rules
- No secrets in code — use AWS Secrets Manager
- All infra changes via Terraform — no manual console changes
- Every feature needs a PR and passing tests
Run /init to let Claude generate a starter version based on your actual project, then edit it.
Claude Code is at its best when it has context about your project, constraints on what it can touch, and clear instructions about your conventions. Invest 30 minutes in your CLAUDE.md and settings once, and every session after that starts with a Claude that already understands your project.
The full documentation is at docs.anthropic.com/claude-code.
