Mastering Claude Code CLI: The Complete Guide for DevOps Engineers

Listen to this article
Click ▶ to start
0%

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 commandsgit, 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:

TypeWhenExamples
CLI CommandsBefore starting a session (in your terminal)claude, claude -p "query", claude --model opus
Slash CommandsDuring a session (inside the REPL)/clear, /compact, /model, /memory
Special NotationsShortcuts while typing a prompt@file.ts, !git status, # note

Special Notations at a Glance

NotationWhat it does
@src/main.pyReference a specific file — Claude reads it immediately
!git statusRun a shell command directly without Claude’s conversational processing
# remember thisAdd 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)

ModeWhat Claude can doBest for
DefaultAsks permission before every changeCareful, step-by-step work; production code; new to Claude Code
Auto-AcceptEdits files without askingFast, repetitive tasks; cleanup; following a well-defined plan
PlanRead-only — cannot change anythingResearch, 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:

  1. Enter Plan Mode (Shift+Tab twice) — give your instruction: “I want to add OAuth2 authentication. Create a detailed plan.”
  2. Review and refine — ask follow-up questions until the plan looks right
  3. 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

FileScopeShared via Git?
~/.claude/CLAUDE.mdAll your projectsNo — personal preferences
./CLAUDE.mdThis projectYes — team-wide conventions
./.claude/CLAUDE.mdThis project (alt)Yes
./CLAUDE.local.mdThis projectNo — 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

ServerWhat it enables
GitHubSearch PRs, read comments, create issues, review code diffs
Postgres / MySQLQuery databases directly, analyse schemas, debug data issues
AWSList resources, check CloudWatch logs, manage S3
Web FetchPull in documentation, error pages, API references
FilesystemRead files outside your project root
SlackPost notifications, read channel history
MemoryPersist information across sessions
DockerInspect 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

EventWhen it fires
SessionStartAt the beginning of every session
UserPromptSubmitWhen you submit a prompt, before Claude begins processing — good for input sanitisation
PreToolUseBefore Claude runs any tool (can block the tool from running)
PermissionRequestWhen Claude displays a permission request dialog
PostToolUseAfter a tool succeeds — includes duration_ms (tool execution time)
PostToolUseFailureAfter a tool fails — also includes duration_ms
NotificationWhen Claude Code sends a notification to the user
SubagentStartWhen a subagent is created
SubagentStopWhen a subagent completes its task
StopWhen Claude finishes generating its response
TeammateIdleWhen an agent team member is about to become idle
TaskCompletedWhen a task is marked completed
ConfigChangeWhen a config file is modified during the session
WorktreeCreateWhen a Git worktree is created via --worktree or isolation settings
WorktreeRemoveWhen a worktree is removed (session ends or subagent finishes)
PreCompactBefore Claude performs context compaction
SessionEndWhen 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:

LanguageStartup timeBest for
Bash~10–20msSimple tasks — string checks, file guards, quick env loads
Node.js~50–100msHigh-frequency hooks (PreToolUse, PostToolUse) — worth the tradeoff for logic-heavy hooks
Python~200–400msLess 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:

ModeBehaviourWhen to use
defaultAsks permission on first use of each toolDaily work, careful changes
acceptEditsAuto-approves all file edits for the sessionRepetitive refactoring, cleanup
planCan read/analyse but cannot modify anythingResearch, planning phase
dontAskDenies everything unless explicitly pre-approvedLocked-down environments
bypassPermissionsSkips all promptsContainers/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:

ScopeFileWho controls it
Managed (highest)managed-settings.json in Claude Code installSystem admin — cannot be overridden by anyone
CLI ArgsSession flags onlyYou, per session
Local.claude/settings.local.jsonYou, per project (gitignored)
Project.claude/settings.jsonTeam, committed to git
User (lowest)~/.claude/settings.jsonYou, 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:

CommandWhat it does
/clearReset conversation history — do this between tasks
/compact [focus]Summarise history, optionally preserving specific areas
/costShow estimated session cost
/usageDetailed token usage breakdown
/contextShow what is taking up context space
/rename [name]Name the current session for easy resumption
/resume [name]Resume a named session
/rewindOpen checkpoint menu (double-tap Esc also works)
/btw [question]Ask a quick side question that never enters history

Configuration & settings:

CommandWhat it does
/configOpen interactive settings UI — one-stop shop for all Claude Code settings
/statusShow all active settings and which layer (managed/project/user) controls each
/permissionsInteractive UI for managing allow/deny/ask rules in real time, no restart needed
/output-styleSwitch response style: Default / Explanatory / Learning
/voicePush-to-talk dictation — hold Space, speak, release

Models & tools:

CommandWhat it does
/model [name]Switch Claude model mid-session
/effort [low|high|xhigh]Control extended thinking
/mcpManage and check MCP servers
/add-dir [path]Add an additional directory to Claude’s working scope

Project & memory:

CommandWhat it does
/initGenerate a starter CLAUDE.md for the current project
/memoryView and edit CLAUDE.md and auto memory
/hooksView configured hooks

Code quality:

CommandWhat it does
/reviewRun a code review subagent
/ultrareviewMulti-agent cloud review — finds and verifies real bugs before you merge (costs $5–$20 per run)
/statuslineGenerate a status bar script and configure it automatically
/doctorDiagnose 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:

ActionShortcut
Focus Claude inputCmd+Esc
Insert file referenceOption+K
New conversationCmd+N
Open in new tabCmd+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:

ComponentApproximate 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.

ResumeFork
Session IDSameNew
BehaviourContinues from where you left offCopies history, branches off
Original sessionGets new messages addedStays unchanged
Use whenContinuing the same workExperimenting 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:

OptionWhat it does
Restore Code OnlyReverts file changes, keeps the conversation — good when code went wrong but context is still useful
Restore Conversation OnlyRewinds the chat, keeps the code — good when you want to re-prompt differently without changing files
Restore BothFull reset — code and conversation go back together
Summarize from hereCondenses 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:

LevelWhat it meansBest for
TerminalRun Claude locally with gh CLI and GitHub MCPPair programming, daily dev work
GitHub Actions (@claude bot)Tag @claude on any issue or PR comment; bot runs Claude automaticallyCode review, bug fixes, async team workflows
Headless / Scriptingclaude -p "..." flag in CI/CD pipelines, cron jobs, scriptsAutomated 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:

  1. Gather context — runs git status, git diff, git log, and git diff main..HEAD to understand every change
  2. Prepare the branch — checks that you are on a feature branch (creates one if needed) and pushes to remote
  3. Analyse changes — reads the diff, identifies the purpose of each change, groups related changes
  4. Create the PR — runs gh pr create with 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:

CommandWhat it does
/commitStages changed files and writes a smart commit message based on the diff
/commit-push-prCommits, pushes the branch, and opens a PR — all in one step
/clean_goneRemoves 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:

  1. Installs the Claude GitHub App from github.com/apps/claude to your repo
  2. Creates a PR containing .github/workflows/claude.yml
  3. Before merging that PR, add ANTHROPIC_API_KEY as a GitHub Secret: Settings → Secrets and variables → Actions
  4. 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:

  1. Press /voice to start a voice session
  2. Hold Space to record, release to submit
  3. 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:

StyleWhat it doesBest for
DefaultConcise, direct answers — just the resultProduction work, experienced users
ExplanatoryAdds “Insight” blocks after each section explaining why a choice was madeCode review, understanding unfamiliar patterns
LearningLeaves TODO(human): markers where you should fill in the next step yourselfActively 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:

ScenarioWhat 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.


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.

Abhay

Abhay Pratap Singh

DevOps Engineer passionate about automation, cloud infrastructure, and self-hosted tools. I write about Kubernetes, Terraform, DNS, and everything in between.