> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/ComposioHQ/agent-orchestrator/llms.txt
> Use this file to discover all available pages before exploring further.

# Claude Code Agent Plugin

> Run Anthropic's Claude Code CLI with automatic metadata tracking and session introspection

The Claude Code agent plugin integrates Anthropic's Claude CLI into the Agent Orchestrator, providing post-launch prompt delivery, automatic PR metadata updates, and cost tracking via JSONL session introspection.

## Overview

Claude Code is Anthropic's official CLI for AI-assisted coding. The plugin:

* Launches Claude in interactive mode (not one-shot)
* Delivers prompts post-launch via `sendMessage()` to keep Claude in conversation mode
* Automatically updates session metadata on PR creation and git operations via PostToolUse hooks
* Extracts cost, token usage, and summaries from Claude's JSONL session files
* Detects activity state by monitoring JSONL file modifications

<Info>
  This plugin requires Claude Code CLI to be installed. Get it from [Anthropic's website](https://claude.ai/code).
</Info>

## Installation

```bash theme={null}
# Install Claude Code CLI
npm install -g @anthropic-ai/claude-code

# Verify installation
which claude
```

## Configuration

Configure in `agent-orchestrator.yaml`:

```yaml theme={null}
plugins:
  agent: claude-code

projects:
  - name: my-project
    path: ~/code/my-project
    agentConfig:
      model: claude-sonnet-4.5
      permissions: suggest
      systemPrompt: |
        You are a senior engineer working on a production codebase.
        Always write tests for new features.
```

### Configuration Options

<ParamField path="model" type="string">
  Claude model to use (e.g., `claude-sonnet-4.5`, `claude-opus-4`)
</ParamField>

<ParamField path="permissions" type="enum">
  Permission mode:

  * `skip`: Auto-approve all operations (`--dangerously-skip-permissions`)
  * `suggest`: Prompt for untrusted operations (default)
  * `ask`: Always prompt
</ParamField>

<ParamField path="systemPrompt" type="string">
  Additional instructions appended to Claude's system prompt
</ParamField>

<ParamField path="systemPromptFile" type="string">
  Path to a file containing system prompt (preferred for long prompts)
</ParamField>

## Automatic Metadata Updates

The plugin installs a PostToolUse hook script (`.claude/metadata-updater.sh`) that automatically updates session metadata when agents run specific commands:

### Tracked Commands

| Command | Metadata Updated |
| - | - |
| `gh pr create` | `pr` (URL), `status` (pr\_open) |
| `git checkout -b <branch>` | `branch` |
| `git switch -c <branch>` | `branch` |
| `gh pr merge` | `status` (merged) |

<Accordion title="How metadata updates work">
  1. Claude Code invokes PostToolUse hooks after each Bash tool call
  2. Hook script receives JSON with tool name, command, and output
  3. Script parses output for PR URLs or branch names
  4. Updates `~/.ao-sessions/<project>/<session-id>` via `update_metadata_key()`
  5. Orchestrator reads updated metadata on next refresh

  The hook is automatically installed on agent launch via `postLaunchSetup()`.
</Accordion>

### Manual Metadata Updates

If hooks fail or you need custom metadata:

```bash theme={null}
# In the agent's workspace, source the helper
source .claude/metadata-updater.sh

# Update any key
update_metadata_key custom_field "value"
```

## Session Introspection

The plugin reads Claude's JSONL session files from `~/.claude/projects/{encoded-path}/` to extract:

### Cost Tracking

Token usage and estimated costs from usage events:

```typescript theme={null}
// Aggregates all token_count events in the session
const cost: CostEstimate = {
  inputTokens: 125000,
  outputTokens: 15000,
  estimatedCostUsd: 0.60  // Based on Sonnet 4.5 pricing
};
```

<Note>
  Cost estimates use Sonnet 4.5 pricing ($3/1M input, $15/1M output) as a baseline. Actual costs may vary for Opus or Haiku models.
</Note>

### Session Summaries

Auto-generated summaries from Claude's summary events:

```json theme={null}
{
  "summary": "Implemented user authentication with JWT tokens",
  "isFallback": false
}
```

If no summary exists, falls back to the first user message (truncated to 120 chars).

### Activity Detection

The plugin monitors JSONL file modifications to detect agent state:

| Last JSONL Event | Agent State | Condition |
| - | - | - |
| `user`, `tool_use`, `progress` | `active` | Recent (\< threshold) |
| `assistant`, `result`, `summary` | `ready` | Recent (\< threshold) |
| `permission_request` | `waiting_input` | Any time |
| `error` | `blocked` | Any time |
| Any event | `idle` | Stale (> threshold) |
| No process | `exited` | Process not running |

<ParamField path="readyThresholdMs" type="number" default="30000">
  Time in milliseconds before an agent is considered idle
</ParamField>

## Usage Examples

### Spawn an Agent

```bash theme={null}
ao spawn my-project "Fix type errors in src/index.ts"
```

The orchestrator:

1. Creates a workspace (git worktree or clone)
2. Launches Claude with the prompt delivered post-launch
3. Installs the metadata updater hook
4. Monitors JSONL for activity and cost

### Resume a Session

```bash theme={null}
ao resume my-project agent-123
```

The plugin builds a restore command using the session UUID from Claude's JSONL filename:

```bash theme={null}
claude --resume abc123-def456 --model claude-sonnet-4.5
```

### View Session Info

```bash theme={null}
ao list --verbose
```

Output includes:

* Session summary (from JSONL)
* Estimated cost
* Token usage
* Activity state

## Advanced Features

### JSONL Path Encoding

Claude stores sessions at `~/.claude/projects/{encoded-path}/`, where `encoded-path` is the workspace path with `/` and `.` replaced by `-`:

```typescript theme={null}
// /Users/dev/.worktrees/ao → Users-dev--worktrees-ao
function toClaudeProjectPath(workspacePath: string): string {
  return workspacePath.replace(/[/.]/g, "-");
}
```

<Warning>
  If Claude changes this encoding scheme, session introspection will silently fail. Validate by checking if the resulting directory exists.
</Warning>

### Long Command Handling

For system prompts exceeding 2000 characters, the plugin uses shell command substitution to avoid tmux truncation:

```bash theme={null}
claude --append-system-prompt "$(cat /path/to/prompt.txt)"
```

### Process Detection

The plugin checks if Claude is running by:

1. **Tmux runtime**: Find the pane's TTY, then search `ps` output for `claude` on that TTY
2. **Process runtime**: Check if the PID in `handle.data.pid` is alive via `process.kill(pid, 0)`

### Cache Optimization

The plugin caches `ps` output for 5 seconds to avoid spawning multiple concurrent `ps` processes when listing many sessions:

```typescript theme={null}
const PS_CACHE_TTL_MS = 5_000;
const psCache: { output: string; timestamp: number } | null;
```

## Troubleshooting

<Accordion title="Hook script not updating metadata">
  **Cause**: Hook not installed or AO\_SESSION not set

  **Solution**:

  1. Check if `.claude/metadata-updater.sh` exists in workspace
  2. Verify hook is registered in `.claude/settings.json`:
     ```json theme={null}
     {
       "hooks": {
         "PostToolUse": [
           {
             "matcher": "Bash",
             "hooks": [{
               "type": "command",
               "command": "/path/to/.claude/metadata-updater.sh"
             }]
           }
         ]
       }
     }
     ```
  3. Check if `AO_SESSION` environment variable is set (should be session ID)
</Accordion>

<Accordion title="Session introspection returns null">
  **Cause**: JSONL file not found or path encoding mismatch

  **Solution**:

  1. Check if `~/.claude/projects/` contains a matching directory
  2. Manually encode the workspace path and verify:
     ```bash theme={null}
     # For /Users/dev/project
     ls ~/.claude/projects/Users-dev-project/
     ```
  3. Ensure Claude has created at least one session file (\*.jsonl)
</Accordion>

<Accordion title="Cost estimates seem wrong">
  **Cause**: Plugin uses Sonnet 4.5 pricing for all models

  **Solution**: Cost estimates are approximate. For accurate billing:

  * Check Anthropic's usage dashboard
  * Parse the `costUSD` field from JSONL if available (newer Claude versions)
  * Adjust pricing in plugin source for other models (requires rebuild)
</Accordion>

<Accordion title="Agent stuck in 'active' state when idle">
  **Cause**: `readyThresholdMs` too long, or permission prompt not detected

  **Solution**:

  1. Adjust threshold in config:
     ```yaml theme={null}
     agentConfig:
       readyThresholdMs: 15000  # 15 seconds
     ```
  2. Check terminal output for permission prompts (run `ao status <session>`)
  3. Attach to session to manually approve: `tmux attach -t <session-id>`
</Accordion>

<Accordion title="Claude launches in one-shot mode (exits after response)">
  **Cause**: Using `-p` flag for prompt delivery

  **Solution**: This plugin intentionally avoids `-p` to keep Claude in interactive mode. Prompts are delivered post-launch via `runtime.sendMessage()`. Do not modify the launch command to include `-p`.
</Accordion>

## Comparison with Other Agents

| Feature | Claude Code | Codex | Aider | OpenCode |
| - | - | - | - | - |
| **Provider** | Anthropic | OpenAI | Aider.chat | OpenCode |
| **Session Files** | JSONL | JSONL | Markdown | SQLite |
| **Cost Tracking** | ✅ Full | ✅ Full | ❌ None | ❌ None |
| **Auto-metadata** | ✅ PostToolUse hooks | ✅ PATH wrappers | ❌ None | ❌ None |
| **Resume Support** | ✅ Native | ✅ Native | ❌ None | ❌ None |
| **Activity Detection** | ✅ JSONL events | ✅ File mtime | ⚠️ Git commits only | ❌ None |

## Environment Variables

The plugin sets these environment variables for introspection:

<ParamField path="AO_SESSION_ID" type="string" required>
  Session identifier for metadata lookups
</ParamField>

<ParamField path="AO_PROJECT_ID" type="string">
  Project identifier (set by caller, not the plugin)
</ParamField>

<ParamField path="AO_ISSUE_ID" type="string">
  Issue/ticket identifier if applicable
</ParamField>

<ParamField path="CLAUDECODE" type="string" default="">
  Unset to avoid nested agent conflicts
</ParamField>

<Info>
  The plugin explicitly unsets `CLAUDECODE` to prevent nested Claude instances from interfering with each other.
</Info>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.