Claude Code Skill for Hermes Agent: Orchestration Guide
Delegate coding to Claude Code CLI (features, PRs).
Written by Neura Market from the official Hermes Agent documentation for Claude Code. Commands, paths, and version numbers are reproduced from the source unchanged.
Read the official documentationThe Claude Code skill lets a Hermes agent hand coding work to Anthropic's autonomous coding CLI and collect the result. It is the skill to reach for when a task means editing files, running tests, opening a review, or pushing a branch, and you want an agent runtime to drive that work rather than a human at a keyboard. This guide walks through both orchestration modes, the flags that matter, and the failure points that catch people on a first run.
What it does
Claude Code is a command-line coding agent from Anthropic. It reads files, writes code, runs shell commands, spawns subagents, and manages git workflows on its own. The Hermes skill wraps that CLI so a Hermes agent can invoke it through the terminal tool, either as a one-shot job or as a long-running interactive session inside tmux.
The skill ships bundled with Hermes Agent, so there is nothing to install on the Hermes side. The skill lives at skills/autonomous-ai-agents/claude-code, is version 2.2.1, authored by Hermes Agent + Teknium, and is MIT licensed. It runs on linux, macos, and windows.
In practice the skill gives you two shapes of work. Print mode is a single command that runs a task, returns a result, and exits. Interactive mode is a full terminal UI that you drive with keystrokes through tmux. Most automation should use the first. The second exists for iterative work where you need to see what Claude is doing and answer it.
Before you start
Install the CLI
npm install -g @anthropic-ai/claude-code
This installs the claude binary globally through npm. You need Node and npm available on the machine where Hermes runs, because the agent shells out to this binary.
Authenticate
Run claude once to log in. Pro and Max subscribers get a browser OAuth flow. Alternatively, set the ANTHROPIC_API_KEY environment variable and skip the browser step.
Two other auth paths exist for organisations:
claude auth login --consolefor API key billing through the Console.claude auth login --ssofor Enterprise single sign-on.
To check where you stand, claude auth status returns JSON, and claude auth status --text returns a human-readable version. The text form is the one to read yourself; the JSON form is the one to parse in a script.
Verify the install
claude doctor runs health checks on the installation and the auto-updater. claude --version confirms the version, and the skill requires v2.x or later. To move forward, claude update or claude upgrade pulls the latest release.
What this implies in practice
Because the skill drives a separate CLI, every prerequisite is a prerequisite for the Hermes host, not for the skill package. If claude is not on the PATH that Hermes uses, the terminal call fails before any coding happens. If auth has expired, print mode fails at the first API call. Run claude doctor and claude auth status --text once when you set up a new machine, and you will not spend a debugging session on either.
Two orchestration modes
Hermes talks to Claude Code in two fundamentally different ways. Pick based on the shape of the task, not on habit.
Mode 1: Print mode (-p), non-interactive
Print mode runs a one-shot task, returns the result, and exits. There is no PTY, no interactive prompt, and no dialog to answer. The source calls this the preferred path for most tasks, and it is the cleanest integration.
terminal(command="claude -p 'Add error handling to all API calls in src/' --allowedTools 'Read,Edit' --max-turns 10", workdir="/path/to/project", timeout=120)
This single terminal call is the whole pattern. The workdir keeps Claude pointed at the right project. --allowedTools 'Read,Edit' restricts it to reading and editing files, so it cannot run shell commands. --max-turns 10 caps the agentic loop so a confused run cannot spin indefinitely.
Reach for print mode when:
- The task is a one-shot fix, feature, or refactor.
- You are wiring coding into CI/CD or a script.
- You want structured data back, using
--json-schema. - You are piping content in, as in
cat file | claude -p "analyze this". - You do not need a back-and-forth conversation.
Print mode skips every interactive dialog: no workspace trust prompt, no permission confirmations. That is exactly why it suits automation, and exactly why you should be deliberate about --allowedTools when you use it.
Mode 2: Interactive PTY via tmux, multi-turn sessions
Interactive mode gives you the full conversational REPL. You can send follow-up prompts, use slash commands, and watch Claude work as it happens. It requires tmux orchestration.
# Start a tmux session
terminal(command="tmux new-session -d -s claude-work -x 140 -y 40")
# Launch Claude Code inside it
terminal(command="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)
terminal(command="sleep 5 && tmux send-keys -t claude-work 'Refactor the auth module to use JWT tokens' Enter")
# Monitor progress by capturing the pane
terminal(command="sleep 15 && tmux capture-pane -t claude-work -p -S -50")
# Send follow-up tasks
terminal(command="tmux send-keys -t claude-work 'Now add unit tests for the new JWT code' Enter")
# Exit when done
terminal(command="tmux send-keys -t claude-work '/exit' Enter")
Read that sequence as a lifecycle. You create a detached tmux session with a fixed size. You launch claude inside it. You wait for the welcome screen, then type the task. You capture the pane to see progress. You type follow-ups. You exit with /exit.
Use interactive mode when:
- The work is iterative: refactor, review, fix, test.
- A human needs to make decisions along the way.
- You are exploring rather than executing a known task.
- You need Claude's slash commands such as
/compact,/review, or/model.
PTY dialog handling
On first launch, Claude Code can present up to two confirmation dialogs. In interactive mode you must handle them with tmux send-keys. Getting this wrong is the most common reason an orchestrated session stalls.
Dialog 1: workspace trust
On the first visit to a directory, Claude asks whether to trust the folder:
❯ 1. Yes, I trust this folder ← DEFAULT (just press Enter)
2. No, exit
The default selection is the correct one. Send tmux send-keys -t Enter and move on. After the first acceptance for a directory, the trust dialog does not appear again.
Dialog 2: individual permission prompts
During normal operation, each tool use that needs approval (a file write, a shell command, a network call) shows a prompt. Answer that one prompt. This is different from disabling prompts for the whole run.
# Read the prompt before answering it
terminal(command="tmux capture-pane -t <session> -p -S -30")
# Allow this one action (Enter = default "Yes"); Esc declines it
terminal(command="tmux send-keys -t <session> Enter")
Capture the pane first, decide, then send the key. The source is blunt about the alternative: never send a blind Enter on a timer to approve prompts you have not read. That is the bypass flag with extra steps.
A narrower opt-in than the full bypass is --permission-mode acceptEdits. File edits in the working directory are accepted, while shell and other tool calls still prompt. The source recommends using it only in a dedicated worktree after reviewing the task.
A robust dialog handling pattern
# Default launch — keep permission prompts enabled
terminal(command="tmux send-keys -t claude-work 'claude \"your task\"' Enter")
# Handle trust dialog (Enter for default "Yes")
terminal(command="sleep 4 && tmux send-keys -t claude-work Enter")
# Now wait for Claude to work
terminal(command="sleep 15 && tmux capture-pane -t claude-work -p -S -60")
This pattern launches with prompts enabled, accepts the trust dialog once, then captures a generous slice of the pane to see what happened.
Opt-in: --dangerously-skip-permissions
This flag disables permission prompts for the whole run, granting filesystem, shell, and network access with no prompts. The source permits it only in a throwaway worktree or an isolated container.
When the warning dialog appears, the default is the safe answer:
❯ 1. No, exit ← DEFAULT (safe choice)
2. Yes, I accept
To accept, move down and confirm: tmux send-keys -t Down && sleep 0.3 && tmux send-keys -t Enter. Only do this when you deliberately opted into the bypass in an isolated environment. Print mode skips the dialog entirely.
CLI subcommands
The claude binary has a wide surface. These are the subcommands the skill documents.
| 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 -- | Add an MCP server |
claude mcp list | List configured MCP servers |
claude mcp remove | 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 |
Print mode in depth
Structured JSON output
terminal(command="claude -p 'Analyze auth.py for security issues' --output-format json --max-turns 5", workdir="/project", timeout=120)
With --output-format json, the result is a single JSON object:
{
"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 } }
}
The fields worth wiring into your agent logic: session_id for resumption, num_turns for how many agentic loops ran, total_cost_usd for spend tracking, and subtype for success or error detection. The documented subtypes are success, error_max_turns, and error_budget.
Streaming JSON output
For real-time token streaming, combine stream-json with --verbose:
terminal(command="claude -p 'Write a summary' --output-format stream-json --verbose --include-partial-messages", timeout=60)
This returns newline-delimited JSON events. To filter live text with jq:
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, for example rate_limit or billing_error. That is the signal to build retry logic on.
Bidirectional streaming
For real-time input and output together:
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
# Pipe a file for analysis
terminal(command="cat src/auth.py | claude -p 'Review this code for bugs' --max-turns 1", timeout=60)
# Pipe multiple files
terminal(command="cat src/*.py | claude -p 'Find all TODO comments' --max-turns 1", timeout=60)
# Pipe command output
terminal(command="git diff HEAD~3 | claude -p 'Summarize these changes' --max-turns 1", timeout=60)
Piping is the cheap path when you already know which content matters. You hand Claude the bytes instead of asking it to go read files, which saves turns and tokens.
JSON schema for structured extraction
terminal(command="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", workdir="/project", timeout=90)
Parse structured_output from the JSON result. Claude validates its output against the schema before returning it, so downstream code can trust the shape.
Session continuation
# Start a task
terminal(command="claude -p 'Start refactoring the database layer' --output-format json --max-turns 10 > ~/.hermes/cache/scratch/session.json", workdir="/project", timeout=180)
# Resume with session ID
terminal(command="claude -p 'Continue and add connection pooling' --resume $(cat ~/.hermes/cache/scratch/session.json | python -c 'import json,sys; print(json.load(sys.stdin)[\"session_id\"])') --max-turns 5", workdir="/project", timeout=120)
# Or resume the most recent session in the same directory
terminal(command="claude -p 'What did you do last time?' --continue --max-turns 1", workdir="/project", timeout=30)
# Fork a session (new ID, keeps history)
terminal(command="claude -p 'Try a different approach' --resume <id> --fork-session --max-turns 10", workdir="/project", timeout=120)
This is how you split a large job across several agent calls without losing context. Save the JSON result, extract session_id, and pass it to --resume. --continue is the shortcut when you just want the most recent session in the current directory. --fork-session branches from an existing session under a new ID while keeping the history, which is useful for trying an alternative approach without contaminating the original run.
Bare mode for CI and scripting
terminal(command="claude --bare -p 'Run all tests and report failures' --allowedTools 'Read,Bash' --max-turns 10", workdir="/project", timeout=180)
--bare skips hooks, plugins, MCP discovery, and CLAUDE.md loading. It gives the fastest startup. It also requires ANTHROPIC_API_KEY, because it skips OAuth.
If you need some context back in bare mode, load it selectively:
| To load | Flag |
|---|---|
| System prompt additions | --append-system-prompt "text" or --append-system-prompt-file path |
| Settings | --settings |
| MCP servers | --mcp-config |
| Custom agents | --agents '' |
Fallback model for overload
terminal(command="claude -p 'task' --fallback-model haiku --max-turns 5", timeout=90)
When the default model is overloaded, print mode automatically falls back to the specified model. This is print-mode only.
Complete CLI flags reference
Session and environment
| Flag | Effect |
|---|---|
-p, --print | Non-interactive one-shot mode (exits when done) |
-c, --continue | Resume most recent conversation in current directory |
-r, --resume | 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 | Use a specific UUID for the conversation |
--no-session-persistence | Don't save session to disk (print mode only) |
--add-dir | Grant Claude access to additional working directories |
-w, --worktree [name] | Run in an isolated git worktree at .claude/worktrees/ |
--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 | File resources to download at startup (format: file_id:relative_path) |
Model and performance
| Flag | Effect |
|---|---|
--model | Model selection: sonnet, opus, haiku, or full name like claude-sonnet-4-6 |
--effort | Reasoning depth: low, medium, high, xhigh, max |
--max-turns | Limit agentic loops (print mode only; prevents runaway) |
--max-budget-usd | Cap API spend in dollars (print mode only) |
--fallback-model | Auto-fallback when default model is overloaded (print mode only) |
--betas | Beta headers to include in API requests (API key users only) |
Permission and safety
| Flag | Effect |
|---|---|
--dangerously-skip-permissions | Opt-in only: disables ALL permission prompts (file writes, bash, network). Throwaway worktree / isolated container only, see "Opt-in" above |
--allow-dangerously-skip-permissions | Enable bypass as an option without enabling it by default |
--permission-mode | default, acceptEdits, plan, auto, dontAsk, bypassPermissions |
--allowedTools | Whitelist specific tools (comma or space-separated) |
--disallowedTools | Blacklist specific tools |
--tools | Override built-in tool set ("" = none, "default" = all, or tool names) |
Output and input format
| Flag | Effect |
|---|---|
--output-format | text (default), json (single result object), stream-json (newline-delimited) |
--input-format | text (default) or stream-json (real-time streaming input) |
--json-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 and context
| Flag | Effect |
|---|---|
--append-system-prompt | Add to the default system prompt (preserves built-in capabilities) |
--append-system-prompt-file | Add file contents to the default system prompt |
--system-prompt | Replace the entire system prompt (use --append instead usually) |
--system-prompt-file | Replace the system prompt with file contents |
--bare | Skip hooks, plugins, MCP discovery, CLAUDE.md, OAuth (fastest startup) |
--agents '' | Define custom subagents dynamically as JSON |
--mcp-config | Load MCP servers from JSON file (repeatable) |
--strict-mcp-config | Only use MCP servers from --mcp-config, ignoring all other MCP configs |
--settings | Load additional settings from a JSON file or inline JSON |
--setting-sources | Comma-separated sources to load: user, project, local |
--plugin-dir | 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 | Write debug logs to file (implicitly enables debug mode) |
Agent teams
| Flag | Effect |
|---|---|
--teammate-mode | How agent teams display: auto, in-process, or tmux |
--brief | Enable SendUserMessage tool for agent-to-user communication |
Tool name syntax for --allowedTools and --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
This syntax is the difference between a safe automation and an accident. Read alone is fine for reviews. Read,Edit covers most refactors. Adding Bash widens the blast radius, so scope it with patterns like Bash(git *) when you can.
Settings and configuration
Settings hierarchy
From highest to lowest priority:
- CLI flags, which override everything.
- Local project settings in
.claude/settings.local.json(personal, gitignored). - Project settings in
.claude/settings.json(shared, git-tracked). - User settings in
~/.claude/settings.json(global).
Permissions in settings
{
"permissions": {
"allow": ["Bash(npm run lint:*)", "WebSearch", "Read"],
"ask": ["Write(*.ts)", "Bash(git push*)"],
"deny": ["Read(.env)", "Bash(rm -rf *)"]
}
}
This is where you encode policy once instead of repeating flags on every call. The deny list is the one to get right first: secrets and destructive shell patterns belong there.
Memory files (CLAUDE.md) hierarchy
- Global:
~/.claude/CLAUDE.md, applies to all projects. - Project:
./CLAUDE.md, project-specific context, git-tracked. - Local:
.claude/CLAUDE.local.md, personal project overrides, gitignored.
In interactive mode, the # prefix quickly adds to memory: # Always use 2-space indentation.
Interactive session: slash commands
Session and 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 | 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 and 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 and tools
| Command | Purpose |
|---|---|
/model [model] | Switch models mid-session (use arrow keys to adjust effort) |
/effort [level] | Set reasoning effort: low, medium, high, xhigh, or max |
/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 for project-shared commands or ~/.claude/commands/<name>.md for personal ones:
# .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)
Invoke it as /deploy production. The $ARGUMENTS placeholder is replaced with whatever the user typed.
Skills
Slash commands are invoked manually. Skills in .claude/skills/ are markdown guides that Claude invokes automatically when natural language matches the task:
# .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 permission modes (Normal → Auto-Accept → Plan) |
Alt+P | Switch model |
Alt+T | Toggle thinking mode |
Alt+O | Toggle Fast Mode |
Multiline input
| Key | Action |
|---|---|
\ + Enter | Quick newline |
Shift+Enter | Newline (alternative) |
Ctrl+J | Newline (alternative) |
Input prefixes
| Prefix | Action |
|---|---|
! | Execute bash directly, bypassing AI (e.g., !npm test). Use ! alone to toggle shell mode. |
@ | Reference files/directories with autocomplete (e.g., @./src/api/) |
# | Quick add to CLAUDE.md memory (e.g., # Use 2-space indentation) |
/ | Slash commands |
The "ultrathink" keyword
Putting "ultrathink" in a prompt triggers the deepest thinking mode for that turn, regardless of the current /effort setting. It is a per-turn override rather than a session-wide change.
PR review patterns
Quick review in print mode
terminal(command="cd /path/to/repo && git diff main...feature-branch | claude -p 'Review this diff for bugs, security issues, and style problems. Be thorough.' --max-turns 1", timeout=60)
Piping the diff in keeps the review focused on the change rather than the whole repository, and --max-turns 1 keeps it to a single pass.
Deep review with interactive mode and a worktree
terminal(command="tmux new-session -d -s review -x 140 -y 40")
terminal(command="tmux send-keys -t review 'cd /path/to/repo && claude -w pr-review' Enter")
terminal(command="sleep 5 && tmux send-keys -t review Enter") # Trust dialog
terminal(command="sleep 2 && tmux send-keys -t review 'Review all changes vs main. Check for bugs, security issues, race conditions, and missing tests.' Enter")
terminal(command="sleep 30 && tmux capture-pane -t review -p -S -60")
This launches Claude inside an isolated worktree named pr-review, accepts the trust dialog, sends a thorough review prompt, and captures the pane after a wait.
Review a PR by number
terminal(command="claude -p 'Review this PR thoroughly' --from-pr 42 --max-turns 10", workdir="/path/to/repo", timeout=120)
--from-pr resumes the session linked to a specific GitHub PR, so you do not have to fetch and pipe the diff yourself.
Worktree with tmux
terminal(command="claude -w feature-x --tmux", workdir="/path/to/repo")
This creates an isolated git worktree at .claude/worktrees/feature-x and a tmux session for it. It uses iTerm2 native panes when available; add --tmux=classic for traditional tmux.
Parallel Claude instances
Independent tasks can run side by side, each in its own tmux session:
# Task 1: Fix backend
terminal(command="tmux new-session -d -s task1 -x 140 -y 40 && tmux send-keys -t task1 'cd ~/project && claude -p \"Fix the auth bug in src/auth.py\" --allowedTools \"Read,Edit\" --max-turns 10' Enter")
# Task 2: Write tests
terminal(command="tmux new-session -d -s task2 -x 140 -y 40 && tmux send-keys -t task2 'cd ~/project && claude -p \"Write integration tests for the API endpoints\" --allowedTools \"Read,Write,Bash\" --max-turns 15' Enter")
# Task 3: Update docs
terminal(command="tmux new-session -d -s task3 -x 140 -y 40 && tmux send-keys -t task3 'cd ~/project && claude -p \"Update README.md with the new API endpoints\" --allowedTools \"Read,Edit\" --max-turns 5' Enter")
# Monitor all
terminal(command="sleep 30 && for s in task1 task2 task3; do echo '=== '$s' ==='; tmux capture-pane -t $s -p -S -5 2>/dev/null; done")
Each task gets its own tool whitelist and turn budget. The monitor loop captures a short tail from each session so you can see whether they are still working or waiting.
CLAUDE.md, the project context file
Claude Code auto-loads CLAUDE.md from the project root. Use it to persist the context that would otherwise be repeated in every prompt:
# Project: My API
## Architecture
- FastAPI backend with SQLAlchemy ORM
- PostgreSQL database, Redis cache
- pytest for testing with 90% coverage target
## Key Commands
- `make test` — run full test suite
- `make lint` — ruff + mypy
- `make dev` — start dev server on :8000
## Code Standards
- Type hints on all public functions
- Docstrings in Google style
- 2-space indentation for YAML, 4-space for Python
- No wildcard imports
Be specific. "Write good code" is not an instruction. "Use 2-space indentation for JS" and "Name test files with .test.ts suffix" are. Specific instructions save correction cycles.
Rules directory
For projects with many rules, use a rules directory instead of one enormous CLAUDE.md:
- Project rules:
.claude/rules/*.md, team-shared, git-tracked. - User rules:
~/.claude/rules/*.md, personal, global.
Each .md file in the rules directory is loaded as additional context.
Auto-memory
Claude stores learned project context in ~/.claude/projects/<project>/memory/. The limit is 25KB or 200 lines per project. This is separate from CLAUDE.md: it is Claude's own notes about the project, accumulated across sessions.
Custom subagents
Define specialised agents in .claude/agents/ (project), ~/.claude/agents/ (personal), or through the --agents CLI flag (session).
Agent location priority
.claude/agents/, project-level, team-shared.--agentsCLI flag, session-specific, dynamic.~/.claude/agents/, user-level, personal.
Creating an agent
# .claude/agents/security-reviewer.md
---
name: security-reviewer
description: Security-focused code review
model: opus
tools: [Read, Bash]
---
You are a senior security engineer. Review code for:
- Injection vulnerabilities (SQL, XSS, command injection)
- Authentication/authorization flaws
- Secrets in code
- Unsafe deserialization
Invoke it with @security-reviewer review the auth module.
Dynamic agents via CLI
terminal(command="claude --agents '{\"reviewer\": {\"description\": \"Reviews code\", \"prompt\": \"You are a code reviewer focused on performance\"}}' -p 'Use @reviewer to check auth.py'", timeout=120)
Claude can orchestrate several agents in one prompt, for example: "Use @db-expert to optimize queries, then @security to audit the changes."
Hooks
Hooks run commands on events. Configure them in .claude/settings.json (project) or ~/.claude/settings.json (global):
{
"hooks": {
"PostToolUse": [{
"matcher": "Write(*.py)",
"hooks": [{"type": "command", "command": "ruff check --fix $CLAUDE_FILE_PATHS"}]
}],
"PreToolUse": [{
"matcher": "Bash",
"hooks": [{"type": "command", "command": "if echo \"$CLAUDE_TOOL_INPUT\" | grep -q 'rm -rf'; then echo 'Blocked!' && exit 2; fi"}]
}],
"Stop": [{
"hooks": [{"type": "command", "command": "echo 'Claude finished a response' >> ~/.hermes/cache/scratch/claude-activity.log"}]
}]
}
}
The eight hook types
| Hook | When it fires | Common use |
|---|---|---|
UserPromptSubmit | Before Claude processes a user prompt | Input validation, logging |
PreToolUse | Before tool execution | Security gates, block dangerous commands (exit 2 = block) |
PostToolUse | After a tool finishes | Auto-format code, run linters |
Notification | On permission requests or input waits | Desktop notifications, alerts |
Stop | When Claude finishes a response | Completion logging, status updates |
SubagentStop | When a subagent completes | Agent orchestration |
PreCompact | Before context memory is cleared | Backup session transcripts |
SessionStart | When a session begins | Load dev context (e.g., git status) |
Hook environment variables
| Variable | Content |
|---|---|
CLAUDE_PROJECT_DIR | Current project path |
CLAUDE_FILE_PATHS | Files being modified |
CLAUDE_TOOL_INPUT | Tool parameters as JSON |
Security hook example
{
"PreToolUse": [{
"matcher": "Bash",
"hooks": [{"type": "command", "command": "if echo \"$CLAUDE_TOOL_INPUT\" | grep -qE 'rm -rf|git push.*--force|:(){ :|:& };:'; then echo 'Dangerous command blocked!' && exit 2; fi"}]
}]
}
A PreToolUse hook that exits with code 2 blocks the tool call. That is the mechanism for a hard security gate that does not depend on the model's judgement.
MCP integration
MCP servers add external tools: databases, APIs, services.
# GitHub integration
terminal(command="claude mcp add -s user github -- npx @modelcontextprotocol/server-github", timeout=30)
# PostgreSQL queries
terminal(command="claude mcp add -s local postgres -- npx @anthropic-ai/server-postgres --connection-string postgresql://localhost/mydb", timeout=30)
# Puppeteer for web testing
terminal(command="claude mcp add puppeteer -- npx @anthropic-ai/server-puppeteer", timeout=30)
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 and CI mode
terminal(command="claude --bare -p 'Query database' --mcp-config mcp-servers.json --strict-mcp-config", timeout=60)
--strict-mcp-config ignores every MCP server except those loaded from --mcp-config. In chat you can reference MCP resources directly, for example @github:issue://123.
MCP limits and tuning
- Tool descriptions: 2KB cap per server for tool descriptions and server instructions.
- Result size: capped by default; the
maxResultSizeCharsannotation allows up to 500K characters for large outputs. - Output tokens:
export MAX_MCP_OUTPUT_TOKENS=50000caps 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
# Periodic capture to check if Claude is still working or waiting for input
terminal(command="tmux capture-pane -t dev -p -S -10")
Look for these indicators:
❯at the bottom means Claude is waiting for your input, either because it is done or because it is asking a question.●lines mean Claude is actively using tools: reading, writing, running commands.⏵⏵ bypass permissions onis the status bar showing the permissions mode.◐ medium · /effortis the current effort level in the status bar.ctrl+o to expandmeans tool output was truncated and can be expanded interactively.
Context window health
/context in interactive mode shows a coloured grid of context usage. The thresholds that matter:
- Below 70%: normal operation, full precision.
- 70 to 85%: precision starts dropping, consider
/compact. - Above 85%: hallucination risk rises significantly, use
/compactor/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 and performance tips
- Use
--max-turnsin print mode to prevent runaway loops. Start with 5 to 10 for most tasks. - Use
--max-budget-usdfor cost caps. The minimum is about $0.05 for system prompt cache creation. - Use
--effort lowfor simple tasks, which is faster and cheaper. Usehighormaxfor complex reasoning. - Use
--barefor CI and scripting to skip plugin and hook discovery overhead. - Use
--allowedToolsto restrict to only what is needed, for exampleReadonly for reviews. - Use
/compactin interactive sessions when context gets large. - Pipe input instead of having Claude read files when you only need analysis of known content.
- Use
--model haikufor simple tasks and--model opusfor complex multi-step work. - Use
--fallback-model haikuin print mode to handle model overload gracefully. - Start new sessions for distinct tasks. Sessions last 5 hours, and fresh context is more efficient.
- Use
--no-session-persistencein CI to avoid accumulating saved sessions on disk.
When not to use it
The source does not list tasks Claude Code cannot do, but it does draw clear lines around when not to use each mode and each permission setting.
Do not use interactive mode when a one-shot print call will do. Print mode is cleaner, needs no dialog handling, and can return structured output. Reaching for tmux when you do not need multi-turn conversation adds moving parts for no gain.
Do not use --dangerously-skip-permissions outside a throwaway worktree or isolated container. The source is explicit that it grants filesystem, shell, and network access with no prompts, and that the safe default on its warning dialog is "No, exit".
Do not use --permission-mode acceptEdits as a general convenience. The source scopes it to a dedicated worktree after reviewing the task.
Do not use --bare when you depend on hooks, plugins, MCP discovery, or CLAUDE.md. It skips all of them, and it also skips OAuth, so it needs ANTHROPIC_API_KEY.
If your task is better served by a different coding agent, the related skills are the place to look: codex, hermes-agent, and opencode.
Limits and gotchas
- Interactive mode requires tmux. Claude Code is a full TUI application. Using
pty=truealone in the Hermes terminal works, but tmux gives youcapture-panefor monitoring andsend-keysfor input, which the source calls essential for orchestration. - The
--dangerously-skip-permissionswarning dialog defaults to "No, exit". That default is the safe answer. Only send Down then Enter when you deliberately opted into the bypass in an isolated environment. Print mode skips the dialog entirely. - The
--max-budget-usdminimum is about $0.05. System prompt cache creation alone costs that much, and setting lower errors immediately. --max-turnsis print-mode only. It is ignored in interactive sessions.- Claude may use
pythonwhere apythonsymlink is missing. On such systems its bash commands fail on the first try, but it self-corrects. - Session resumption requires the same directory.
--continuefinds the most recent session for the current working directory. --json-schemaneeds enough--max-turns. Claude must read files before producing structured output, which takes multiple turns.- The trust dialog appears only once per directory, then is cached.
- Background tmux sessions persist. Always clean up with
tmux kill-session -t <name>when done. - Slash commands such as
/commitonly work in interactive mode. In-pmode, describe the task in natural language instead. --bareskips OAuth. It requires theANTHROPIC_API_KEYenvironment variable or anapiKeyHelperin settings.- Context degradation is real. Output quality measurably degrades above 70% context window usage. Monitor with
/contextand compact proactively.
Rules for Hermes agents
These are the source's own operating rules for an agent driving this skill.
- Prefer print mode (
-p) for single tasks. It is cleaner, needs no dialog handling, and returns structured output. - Use tmux for multi-turn interactive work. It is the only reliable way to orchestrate the TUI.
- Always set
workdirso Claude stays focused on the right project directory. - Set
--max-turnsin print mode to prevent infinite loops and runaway costs. - Monitor tmux sessions with
tmux capture-pane -t <session> -p -S -50to check progress. - Look for the
❯prompt. It means Claude is waiting for input, either done or asking a question. - Clean up tmux sessions when done to avoid resource leaks.
- Report results to the user. After completion, summarise what Claude did and what changed.
- Do not kill slow sessions. Claude may be doing multi-step work, so check progress instead.
- Use
--allowedToolsto restrict capabilities to what the task actually needs.
What pairs with this
The skill sits in the Autonomous AI Agents category alongside three related skills. codex is the parallel option when you want a different coding agent. hermes-agent covers the runtime itself, which is worth reading if you are writing orchestration logic around this skill. opencode is the third coding-agent option in the bundle. All three are documented in the same section of the Hermes Agent docs.