# Claude Code

> Delegates coding tasks to Anthropic Claude Code CLI (claude, claude -p, claude auth, tmux REPL) for autonomous edits, PRs, JSON print-mode, and CI. Use when invoking Claude Code from a shell. Not for Cursor-native agents, Codex/OpenCode CLIs, or using Claude as Hermes' own model.

- Skill: `gabrielmoreira/claude-code` (Agent Skill, multi-file: 3 files)
- Install (CLI): `npx skillmds@latest add gabrielmoreira/claude-code`
- Raw SKILL.md: https://api.skillmd.com/api/skills/gabrielmoreira/claude-code/raw
- Safety review: pending (external: skill-scanner PASS, skillspector FAIL)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- License: MIT
- Author: gabrielmoreira (https://skillmd.com/u/gabrielmoreira)
- Updated: 2026-09-21
- Page: https://skillmd.com/skills/gabrielmoreira/claude-code

---


# Claude Code — Orchestration Guide

Delegate coding tasks to [Claude Code](https://code.claude.com/docs/en/cli-reference) (Anthropic's autonomous coding agent CLI). Claude Code v2.x reads files, writes code, runs shell commands, spawns subagents, and manages git workflows autonomously.

**Windows host is primary (PowerShell).** When commands use bash syntax (e.g., `cat file | claude -p`), adapt for PowerShell (e.g., `Get-Content file | claude -p`). tmux commands apply when running inside WSL or a Linux/macOS environment.

## When to Use

- One-shot coding tasks: fix a bug, add a feature, refactor a module
- CI/CD automation and scripting with structured JSON output
- Multi-turn iterative work: refactor → review → fix → test cycles
- Code review and security analysis of current changes
- Structured data extraction from codebases using `--json-schema`
- Piped input processing (pipe file contents or command output for analysis)
- Session continuation and resumption across directories

## Prerequisites

1. **Install:** `npm install -g @anthropic-ai/claude-code`
2. **Auth (browser OAuth for Pro/Max):** run `claude` once to log in
3. **API key auth:** set `ANTHROPIC_API_KEY` environment variable
4. **Console auth (API key billing):** `claude auth login --console`
5. **SSO auth (Enterprise):** `claude auth login --sso`
6. **Check status:** `claude auth status` (JSON) or `claude auth status --text` (human-readable)
7. **Health check:** `claude doctor` — checks auto-updater and installation health
8. **Version check:** `claude --version` (requires v2.x+)
9. **Update:** `claude update` or `claude upgrade`

## Procedure

### Mode 1: Print Mode (`-p`) — Non-Interactive (PREFERRED)

Print mode runs a one-shot task, returns the result, and exits. No PTY needed. No interactive prompts. This is the cleanest integration path.

```bash
claude -p "Add error handling to all API calls in src/" --allowedTools "Read,Edit" --max-turns 10
```

PowerShell equivalent:

```powershell
claude -p "Add error handling to all API calls in src/" --allowedTools "Read,Edit" --max-turns 10
```

**Use print mode for:**
- One-shot coding tasks (fix a bug, add a feature, refactor)
- CI/CD automation and scripting
- Structured data extraction with `--json-schema`
- Piped input processing
- Any task where you don't need multi-turn conversation

Print mode skips ALL interactive dialogs — no workspace trust prompt, no permission confirmations.

#### Structured JSON Output

```bash
claude -p "Analyze auth.py for security issues" --output-format json --max-turns 5
```

Returns a JSON object with:

```json
{
  "type": "result",
  "subtype": "success",
  "result": "The analysis text...",
  "session_id": "75e2167f-...",
  "num_turns": 3,
  "total_cost_usd": 0.0787,
  "duration_ms": 10276,
  "stop_reason": "end_turn",
  "terminal_reason": "completed",
  "usage": { "input_tokens": 5, "output_tokens": 603 },
  "modelUsage": { "claude-sonnet-4-6": { "costUSD": 0.078, "contextWindow": 200000 } }
}
```

Key fields: `session_id` for resumption, `num_turns` for agentic loop count, `total_cost_usd` for spend tracking, `subtype` for success/error detection (`success`, `error_max_turns`, `error_budget`).

#### Streaming JSON Output

```bash
claude -p "Write a summary" --output-format stream-json --verbose --include-partial-messages
```

Returns newline-delimited JSON events. Filter with jq for live text:

```bash
claude -p "Explain X" --output-format stream-json --verbose --include-partial-messages | \
  jq -rj 'select(.type == "stream_event" and .event.delta.type? == "text_delta") | .event.delta.text'
```

Stream events include `system/api_retry` with `attempt`, `max_retries`, and `error` fields (e.g., `rate_limit`, `billing_error`).

#### Bidirectional Streaming

```bash
claude -p "task" --input-format stream-json --output-format stream-json --replay-user-messages
```

`--replay-user-messages` re-emits user messages on stdout for acknowledgment.

#### Piped Input

```bash
# Pipe a file for analysis
cat src/auth.py | claude -p "Review this code for bugs" --max-turns 1

# Pipe multiple files
cat src/*.py | claude -p "Find all TODO comments" --max-turns 1

# Pipe command output
git diff HEAD~3 | claude -p "Summarize these changes" --max-turns 1
```

PowerShell equivalents:

```powershell
Get-Content src/auth.py | claude -p "Review this code for bugs" --max-turns 1
Get-Content src/*.py | claude -p "Find all TODO comments" --max-turns 1
git diff HEAD~3 | claude -p "Summarize these changes" --max-turns 1
```

#### JSON Schema for Structured Extraction

```bash
claude -p "List all functions in src/" --output-format json \
  --json-schema '{"type":"object","properties":{"functions":{"type":"array","items":{"type":"string"}}},"required":["functions"]}' \
  --max-turns 5
```

Parse `structured_output` from the JSON result. Claude validates output against the schema before returning.

#### Session Continuation

```bash
# Start a task and save session info
claude -p "Start refactoring the database layer" --output-format json --max-turns 10 > /tmp/session.json

# Resume with session ID
claude -p "Continue and add connection pooling" --resume $(cat /tmp/session.json | python3 -c 'import json,sys; print(json.load(sys.stdin)["session_id"])') --max-turns 5

# Resume the most recent session in the same directory
claude -p "What did you do last time?" --continue --max-turns 1

# Fork a session (new ID, keeps history)
claude -p "Try a different approach" --resume <id> --fork-session --max-turns 10
```

#### Bare Mode for CI/Scripting

```bash
claude --bare -p "Run all tests and report failures" --allowedTools "Read,Bash" --max-turns 10
```

`--bare` skips hooks, plugins, MCP discovery, and CLAUDE.md loading. Fastest startup. Requires `ANTHROPIC_API_KEY` (skips OAuth).

| To load | Flag |
|---------|------|
| System prompt additions | `--append-system-prompt "text"` or `--append-system-prompt-file path` |
| Settings | `--settings <file-or-json>` |
| MCP servers | `--mcp-config <file-or-json>` |
| Custom agents | `--agents '<json>'` |

#### Fallback Model for Overload

```bash
claude -p "task" --fallback-model haiku --max-turns 5
```

Automatically falls back to the specified model when the default is overloaded (print mode only).

### Mode 2: Interactive PTY via tmux — Multi-Turn Sessions

Interactive mode gives you a full conversational REPL where you can send follow-up prompts, use slash commands, and watch Claude work in real time. **Requires tmux orchestration.**

```bash
# Start a tmux session
tmux new-session -d -s claude-work -x 140 -y 40

# Launch Claude Code inside it
tmux send-keys -t claude-work "cd /path/to/project && claude" Enter

# Wait for startup, then send your task (after ~3-5 seconds for the welcome screen)
sleep 5 && tmux send-keys -t claude-work "Refactor the auth module to use JWT tokens" Enter

# Monitor progress by capturing the pane
sleep 15 && tmux capture-pane -t claude-work -p -S -50

# Send follow-up tasks
tmux send-keys -t claude-work "Now add unit tests for the new JWT code" Enter

# Exit when done
tmux send-keys -t claude-work "/exit" Enter
```

**Use interactive mode for:**
- Multi-turn iterative work (refactor → review → fix → test cycle)
- Tasks requiring human-in-the-loop decisions
- Exploratory coding sessions
- When you need Claude's slash commands (`/compact`, `/review`, `/model`)

### PTY Dialog Handling (CRITICAL for Interactive Mode)

Claude Code presents up to two confirmation dialogs on first launch. You MUST handle these via tmux send-keys.

#### Dialog 1: Workspace Trust (first visit to a directory)

```
❯ 1. Yes, I trust this folder    ← DEFAULT (just press Enter)
  2. No, exit
```

**Handling:** `tmux send-keys -t <session> Enter` — default selection is correct.

#### Dialog 2: Bypass Permissions Warning (only with --dangerously-skip-permissions)

```
❯ 1. No, exit                    ← DEFAULT (WRONG choice!)
  2. Yes, I accept
```

**Handling:** Must navigate DOWN first, then Enter:

```bash
tmux send-keys -t <session> Down && sleep 0.3 && tmux send-keys -t <session> Enter
```

#### Robust Dialog Handling Pattern

```bash
# Launch with permissions bypass
tmux send-keys -t claude-work 'claude --dangerously-skip-permissions "your task"' Enter

# Handle trust dialog (Enter for default "Yes")
sleep 4 && tmux send-keys -t claude-work Enter

# Handle permissions dialog (Down then Enter for "Yes, I accept")
sleep 3 && tmux send-keys -t claude-work Down && sleep 0.3 && tmux send-keys -t claude-work Enter

# Now wait for Claude to work
sleep 15 && tmux capture-pane -t claude-work -p -S -60
```

**Note:** After the first trust acceptance for a directory, the trust dialog won't appear again. Only the permissions dialog recurs each time you use `--dangerously-skip-permissions`.

### CLI Subcommands

| Subcommand | Purpose |
|------------|---------|
| `claude` | Start interactive REPL |
| `claude "query"` | Start REPL with initial prompt |
| `claude -p "query"` | Print mode (non-interactive, exits when done) |
| `cat file \| claude -p "query"` | Pipe content as stdin context |
| `claude -c` | Continue the most recent conversation in this directory |
| `claude -r "id"` | Resume a specific session by ID or name |
| `claude auth login` | Sign in (add `--console` for API billing, `--sso` for Enterprise) |
| `claude auth status` | Check login status (returns JSON; `--text` for human-readable) |
| `claude mcp add <name> -- <cmd>` | Add an MCP server |
| `claude mcp list` | List configured MCP servers |
| `claude mcp remove <name>` | Remove an MCP server |
| `claude agents` | List configured agents |
| `claude doctor` | Run health checks on installation and auto-updater |
| `claude update` / `claude upgrade` | Update Claude Code to latest version |
| `claude remote-control` | Start server to control Claude from claude.ai or mobile app |
| `claude install [target]` | Install native build (stable, latest, or specific version) |
| `claude setup-token` | Set up long-lived auth token (requires subscription) |
| `claude plugin` / `claude plugins` | Manage Claude Code plugins |
| `claude auto-mode` | Inspect auto mode classifier configuration |

### Complete CLI Flags Reference

#### Session & Environment

| Flag | Effect |
|------|--------|
| `-p, --print` | Non-interactive one-shot mode (exits when done) |
| `-c, --continue` | Resume most recent conversation in current directory |
| `-r, --resume <id>` | Resume specific session by ID or name (interactive picker if no ID) |
| `--fork-session` | When resuming, create new session ID instead of reusing original |
| `--session-id <uuid>` | Use a specific UUID for the conversation |
| `--no-session-persistence` | Don't save session to disk (print mode only) |
| `--add-dir <paths...>` | Grant Claude access to additional working directories |
| `-w, --worktree [name]` | Run in an isolated git worktree at `.claude/worktrees/<name>` |
| `--tmux` | Create a tmux session for the worktree (requires `--worktree`) |
| `--ide` | Auto-connect to a valid IDE on startup |
| `--chrome` / `--no-chrome` | Enable/disable Chrome browser integration for web testing |
| `--from-pr [number]` | Resume session linked to a specific GitHub PR |
| `--file <specs...>` | File resources to download at startup (format: `file_id:relative_path`) |

#### Model & Performance

| Flag | Effect |
|------|--------|
| `--model <alias>` | Model selection: `sonnet`, `opus`, `haiku`, or full name like `claude-sonnet-4-6` |
| `--effort <level>` | Reasoning depth: `low`, `medium`, `high`, `max`, `auto` |
| `--max-turns <n>` | Limit agentic loops (print mode only; prevents runaway) |
| `--max-budget-usd <n>` | Cap API spend in dollars (print mode only) |
| `--fallback-model <model>` | Auto-fallback when default model is overloaded (print mode only) |
| `--betas <betas...>` | Beta headers to include in API requests (API key users only) |

#### Permission & Safety

| Flag | Effect |
|------|--------|
| `--dangerously-skip-permissions` | Auto-approve ALL tool use (file writes, bash, network, etc.) |
| `--allow-dangerously-skip-permissions` | Enable bypass as an *option* without enabling it by default |
| `--permission-mode <mode>` | `default`, `acceptEdits`, `plan`, `auto`, `dontAsk`, `bypassPermissions` |
| `--allowedTools <tools...>` | Whitelist specific tools (comma or space-separated) |
| `--disallowedTools <tools...>` | Blacklist specific tools |
| `--tools <tools...>` | Override built-in tool set (`""` = none, `"default"` = all, or tool names) |

#### Output & Input Format

| Flag | Effect |
|------|--------|
| `--output-format <fmt>` | `text` (default), `json` (single result object), `stream-json` (newline-delimited) |
| `--input-format <fmt>` | `text` (default) or `stream-json` (real-time streaming input) |
| `--json-schema <schema>` | Force structured JSON output matching a schema |
| `--verbose` | Full turn-by-turn output |
| `--include-partial-messages` | Include partial message chunks as they arrive (stream-json + print) |
| `--replay-user-messages` | Re-emit user messages on stdout (stream-json bidirectional) |

#### System Prompt & Context

| Flag | Effect |
|------|--------|
| `--append-system-prompt <text>` | **Add** to the default system prompt (preserves built-in capabilities) |
| `--append-system-prompt-file <path>` | **Add** file contents to the default system prompt |
| `--system-prompt <text>` | **Replace** the entire system prompt (use --append instead usually) |
| `--system-prompt-file <path>` | **Replace** the system prompt with file contents |
| `--bare` | Skip hooks, plugins, MCP discovery, CLAUDE.md, OAuth (fastest startup) |
| `--agents '<json>'` | Define custom subagents dynamically as JSON |
| `--mcp-config <path>` | Load MCP servers from JSON file (repeatable) |
| `--strict-mcp-config` | Only use MCP servers from `--mcp-config`, ignoring all other MCP configs |
| `--settings <file-or-json>` | Load additional settings from a JSON file or inline JSON |
| `--setting-sources <sources>` | Comma-separated sources to load: `user`, `project`, `local` |
| `--plugin-dir <paths...>` | Load plugins from directories for this session only |
| `--disable-slash-commands` | Disable all skills/slash commands |

#### Debugging

| Flag | Effect |
|------|--------|
| `-d, --debug [filter]` | Enable debug logging with optional category filter (e.g., `"api,hooks"`, `"!1p,!file"`) |
| `--debug-file <path>` | Write debug logs to file (implicitly enables debug mode) |

#### Agent Teams

| Flag | Effect |
|------|--------|
| `--teammate-mode <mode>` | How agent teams display: `auto`, `in-process`, or `tmux` |
| `--brief` | Enable `SendUserMessage` tool for agent-to-user communication |

#### Tool Name Syntax for --allowedTools / --disallowedTools

```
Read                    # All file reading
Edit                    # File editing (existing files)
Write                   # File creation (new files)
Bash                    # All shell commands
Bash(git *)             # Only git commands
Bash(git commit *)      # Only git commit commands
Bash(npm run lint:*)    # Pattern matching with wildcards
WebSearch               # Web search capability
WebFetch                # Web page fetching
mcp__<server>__<tool>   # Specific MCP tool
```

### Settings & Configuration

#### Settings Hierarchy (highest to lowest priority)

1. **CLI flags** — override everything
2. **Local project:** `.claude/settings.local.json` (personal, gitignored)
3. **Project:** `.claude/settings.json` (shared, git-tracked)
4. **User:** `~/.claude/settings.json` (global)

#### Permissions in Settings

```json
{
  "permissions": {
    "allow": ["Bash(npm run lint:*)", "WebSearch", "Read"],
    "ask": ["Write(*.ts)", "Bash(git push*)"],
    "deny": ["Read(.env)", "Bash(rm -rf *)"]
  }
}
```

#### Memory Files (CLAUDE.md) Hierarchy

1. **Global:** `~/.claude/CLAUDE.md` — applies to all projects
2. **Project:** `./CLAUDE.md` — project-specific context (git-tracked)
3. **Local:** `.claude/CLAUDE.local.md` — personal project overrides (gitignored)

Use the `#` prefix in interactive mode to quickly add to memory: `# Always use 2-space indentation`.

### Interactive Session: Slash Commands

#### Session & Context

| Command | Purpose |
|---------|---------|
| `/help` | Show all commands (including custom and MCP commands) |
| `/compact [focus]` | Compress context to save tokens; CLAUDE.md survives compaction. E.g., `/compact focus on auth logic` |
| `/clear` | Wipe conversation history for a fresh start |
| `/context` | Visualize context usage as a colored grid with optimization tips |
| `/cost` | View token usage with per-model and cache-hit breakdowns |
| `/resume` | Switch to or resume a different session |
| `/rewind` | Revert to a previous checkpoint in conversation or code |
| `/btw <question>` | Ask a side question without adding to context cost |
| `/status` | Show version, connectivity, and session info |
| `/todos` | List tracked action items from the conversation |
| `/exit` or `Ctrl+D` | End session |

#### Development & Review

| Command | Purpose |
|---------|---------|
| `/review` | Request code review of current changes |
| `/security-review` | Perform security analysis of current changes |
| `/plan [description]` | Enter Plan mode with auto-start for task planning |
| `/loop [interval]` | Schedule recurring tasks within the session |
| `/batch` | Auto-create worktrees for large parallel changes (5-30 worktrees) |

#### Configuration & Tools

| Command | Purpose |
|---------|---------|
| `/model [model]` | Switch models mid-session (use arrow keys to adjust effort) |
| `/effort [level]` | Set reasoning effort: `low`, `medium`, `high`, `max`, or `auto` |
| `/init` | Create a CLAUDE.md file for project memory |
| `/memory` | Open CLAUDE.md for editing |
| `/config` | Open interactive settings configuration |
| `/permissions` | View/update tool permissions |
| `/agents` | Manage specialized subagents |
| `/mcp` | Interactive UI to manage MCP servers |
| `/add-dir` | Add additional working directories (useful for monorepos) |
| `/usage` | Show plan limits and rate limit status |
| `/voice` | Enable push-to-talk voice mode (20 languages; hold Space to record, release to send) |
| `/release-notes` | Interactive picker for version release notes |

#### Custom Slash Commands

Create `.claude/commands/<name>.md` (project-shared) or `~/.claude/commands/<name>.md` (personal):

```markdown
# .claude/commands/deploy.md
Run the deploy pipeline:
1. Run all tests
2. Build the Docker image
3. Push to registry
4. Update the $ARGUMENTS environment (default: staging)
```

Usage: `/deploy production` — `$ARGUMENTS` is replaced with the user's input.

#### Skills (Natural Language Invocation)

Unlike slash commands (manually invoked), skills in `.claude/skills/` are markdown guides that Claude invokes automatically via natural language when the task matches:

```markdown
# .claude/skills/database-migration.md
When asked to create or modify database migrations:
1. Use Alembic for migration generation
2. Always create a rollback function
3. Test migrations against a local database copy
```

### Interactive Session: Keyboard Shortcuts

#### General Controls

| Key | Action |
|-----|--------|
| `Ctrl+C` | Cancel current input or generation |
| `Ctrl+D` | Exit session |
| `Ctrl+R` | Reverse search command history |
| `Ctrl+B` | Background a running task |
| `Ctrl+V` | Paste image into conversation |
| `Ctrl+O` | Transcript mode — see Claude's thinking process |
| `Ctrl+G` or `Ctrl+X Ctrl+E` | Open prompt in external editor |
| `Esc Esc` | Rewind conversation or code state / summarize |

#### Mode Toggles

| Key | Action |
|-----|--------|
| `Shift+Tab` | Cycle auto-accept / plan / default mode |
| `Tab` | Toggle auto-accept edits mode |

### MCP Integration

Add external tool servers for databases, APIs, and services:

```bash
# GitHub integration
claude mcp add -s user github -- npx @modelcontextprotocol/server-github

# PostgreSQL queries
claude mcp add -s local postgres -- npx @anthropic-ai/server-postgres --connection-string postgresql://localhost/mydb

# Puppeteer for web testing
claude mcp add puppeteer -- npx @anthropic-ai/server-puppeteer
```

#### MCP Scopes

| Flag | Scope | Storage |
|------|-------|---------|
| `-s user` | Global (all projects) | `~/.claude.json` |
| `-s local` | This project (personal) | `.claude/settings.local.json` (gitignored) |
| `-s project` | This project (team-shared) | `.claude/settings.json` (git-tracked) |

#### MCP in Print/CI Mode

```bash
claude --bare -p "Query database" --mcp-config mcp-servers.json --strict-mcp-config
```

`--strict-mcp-config` ignores all MCP servers except those from `--mcp-config`.

Reference MCP resources in chat: `@github:issue://123`

#### MCP Limits & Tuning

- **Tool descriptions:** 2KB cap per server for tool descriptions and server instructions
- **Result size:** Default capped; use `maxResultSizeChars` annotation to allow up to **500K** characters for large outputs
- **Output tokens:** `export MAX_MCP_OUTPUT_TOKENS=50000` — cap output from MCP servers to prevent context flooding
- **Transports:** `stdio` (local process), `http` (remote), `sse` (server-sent events)

### Monitoring Interactive Sessions

#### Reading the TUI Status

```bash
# Periodic capture to check if Claude is still working or waiting for input
tmux capture-pane -t dev -p -S -10
```

Look for these indicators:
- `❯` at bottom = waiting for your input (Claude is done or asking a question)
- `●` lines = Claude is actively using tools (reading, writing, running commands)
- `⏵⏵ bypass permissions on` = status bar showing permissions mode
- `◐ medium · /effort` = current effort level in status bar
- `ctrl+o to expand` = tool output was truncated (can be expanded interactively)

#### Context Window Health

Use `/context` in interactive mode to see a colored grid of context usage. Key thresholds:
- **< 70%** — Normal operation, full precision
- **70-85%** — Precision starts dropping, consider `/compact`
- **> 85%** — Hallucination risk spikes significantly, use `/compact` or `/clear`

### Environment Variables

| Variable | Effect |
|----------|--------|
| `ANTHROPIC_API_KEY` | API key for authentication (alternative to OAuth) |
| `CLAUDE_CODE_EFFORT_LEVEL` | Default effort: `low`, `medium`, `high`, `max`, or `auto` |
| `MAX_THINKING_TOKENS` | Cap thinking tokens (set to `0` to disable thinking entirely) |
| `MAX_MCP_OUTPUT_TOKENS` | Cap output from MCP servers (default varies; set e.g., `50000`) |
| `CLAUDE_CODE_NO_FLICKER=1` | Enable alt-screen rendering to eliminate terminal flicker |
| `CLAUDE_CODE_SUBPROCESS_ENV_SCRUB` | Strip credentials from sub-processes for security |

### Cost & Performance Tips

1. **Use `--max-turns`** in print mode to prevent runaway loops. Start with 5-10 for most tasks.
2. **Use `--max-budget-usd`** for cost caps. Note: minimum ~$0.05 for system prompt cache creation.
3. **Use `--effort low`** for simple tasks (faster, cheaper). `high` or `max` for complex reasoning.
4. **Use `--bare`** for CI/scripting to skip plugin/hook discovery overhead.
5. **Use `--allowedTools`** to restrict to only what's needed (e.g., `Read` only for reviews).
6. **Use `/compact`** in interactive sessions when context gets large.
7. **Pipe input** instead of having Claude read files when you just need analysis of known content.
8. **Use `--model haiku`** for simple tasks (cheaper) and `--model opus` for complex multi-step work.
9. **Use `--fallback-model haiku`** in print mode to gracefully handle model overload.
10. **Start new sessions for distinct tasks** — sessions last 5 hours; fresh context is more efficient.
11. **Use `--no-session-persistence`** in CI to avoid accumulating saved sessions on disk.

### Scripts and References

- **`scripts/claude-cc`** — Wrapper script that unsets `ANTHROPIC_AUTH_TOKEN` and `ANTHROPIC_API_KEY` before `exec claude "$@"`, forcing Claude Code to fall back to browser OAuth. Use this wrapper whenever Claude Code runs as a sub-agent inside Hermes and the host's active provider is not Anthropic. Verify with: `bash scripts/claude-cc -p "say PONG" --max-turns 1`.
- Load reference files from `references/` when you need deeper context on specific topics. Check the directory for available reference documents.

## Pitfalls

1. **Interactive mode REQUIRES tmux** — Claude Code is a full TUI app. Using `pty=true` alone works but tmux gives you `capture-pane` for monitoring and `send-keys` for input, which is essential for orchestration.
2. **`--dangerously-skip-permissions` dialog defaults to "No, exit"** — you must send Down then Enter to accept. Print mode (`-p`) skips this entirely.
3. **`--max-budget-usd` minimum is ~$0.05** — system prompt cache creation alone costs this much. Setting lower will error immediately.
4. **`--max-turns` is print-mode only** — ignored in interactive sessions.
5. **Claude may use `python` instead of `python3`** — on systems without a `python` symlink, Claude's bash commands will fail on first try but it self-corrects.
6. **Session resumption requires same directory** — `--continue` finds the most recent session for the current working directory.
7. **`--json-schema` needs enough `--max-turns`** — Claude must read files before producing structured output, which takes multiple turns.
8. **Trust dialog only appears once per directory** — first-time only, then cached.
9. **Background tmux sessions persist** — always clean up with `tmux kill-session -t <name>` when done.
10. **Slash commands (like `/commit`) only work in interactive mode** — in `-p` mode, describe the task in natural language instead.
11. **`--bare` skips OAuth** — requires `ANTHROPIC_API_KEY` env var or an `apiKeyHelper` in settings.
12. **Context degradation is real** — AI output quality measurably degrades above 70% context window usage. Monitor with `/context` and proactively `/compact`.

### CRITICAL: Injected ANTHROPIC_AUTH_TOKEN breaks OAuth

When Claude Code runs **as a sub-agent inside Hermes**, Hermes injects `ANTHROPIC_AUTH_TOKEN` into the subprocess environment — sourced from the host's model config `api_key` (e.g. the Ollama provider sets `api_key: ollama`, which Hermes exports as `ANTHROPIC_AUTH_TOKEN=ollama`). Claude Code treats that as a bearer and sends it → **401 Invalid bearer token**, even though `claude auth status` reports `loggedIn: true` (it only checks local credential presence, not validity). `env -u ANTHROPIC_API_KEY` alone does NOT fix it — the offending var is `ANTHROPIC_AUTH_TOKEN`.

**Fix:** run Claude Code via the wrapper `scripts/claude-cc`, which unsets `ANTHROPIC_AUTH_TOKEN` and `ANTHROPIC_API_KEY` before `exec claude "$@"`, forcing Claude Code to fall back to browser OAuth (your claude.ai membership). Verify with: `bash scripts/claude-cc -p "say PONG" --max-turns 1`.

**Scope note:** this applies whenever Hermes' active/default provider is not Anthropic but a stale/placeholder Anthropic token leaks into the env. The claude.ai membership (OAuth) can power Claude Code as a *sub-agent*; it **cannot** be Hermes' *own* model — that still requires a real `ANTHROPIC_API_KEY` in Hermes' `.env` + `model.provider=anthropic`.

## Verification

1. **Check installation health:**
   ```bash
   claude doctor
   ```
   Should report no issues with auto-updater and installation.

2. **Verify version (requires v2.x+):**
   ```bash
   claude --version
   ```

3. **Verify auth status:**
   ```bash
   claude auth status --text
   ```
   Should show logged-in status.

4. **Verify print mode works:**
   ```bash
   claude -p "say PONG" --max-turns 1
   ```
   Should output "PONG" and exit.

5. **Verify wrapper (if using scripts/claude-cc):**
   ```bash
   bash scripts/claude-cc -p "say PONG" --max-turns 1
   ```
   Should output "PONG" and exit — confirms OAuth fallback works.

6. **Verify JSON output format:**
   ```bash
   claude -p "What is 2+2" --output-format json --max-turns 1
   ```
   Should return a JSON object with `"subtype": "success"`.

7. **Verify tmux session (interactive mode):**
   ```bash
   tmux new-session -d -s test-claude -x 140 -y 40
   tmux send-keys -t test-claude "claude -p 'say PONG' --max-turns 1" Enter
   sleep 5 && tmux capture-pane -t test-claude -p -S -10
   tmux kill-session -t test-claude
   ```

## Related Skills

- **codex** — Alternative coding agent CLI
- **hermes-agent** — Hermes orchestration framework
- **opencode** — Open-source coding agent

