agent-metrics

Extract accurate per-agent token metrics, timing, and execution statistics from Claude Code session files.

Overview

Claude Code's Task tool reports only total_tokens without input/output/cache breakdown. @uluops/agent-metrics extracts accurate per-agent metrics from the underlying JSONL session files, providing complete token counts, timing, and execution statistics.

Installation

bash
# Global (recommended)
npm install -g @uluops/agent-metrics

# Or from source
cd packages/agent-metrics
npm install && npm run build && npm link

Requirements: Node.js 18+, Claude Code installed

Quick Start

bash
# Show recent auto-captured metrics
agent-metrics report

# List recent agent runs
agent-metrics list

# Extract metrics for a specific agent
agent-metrics extract a80e24f

# Compare multiple agents side-by-side
agent-metrics compare a5b1804 ac51171 a0a96d3

How It Works

Claude Code stores detailed execution data in JSONL files at ~/.claude/projects/{project}/agent-{id}.jsonl. Each file contains all messages from an agent invocation including prompts, responses with token usage, tool invocations, and timestamps.

agent-metrics reads these files to produce accurate token breakdowns:

MetricCalculationUse Case
total_effectiveinput + cache_creation + outputBilling approximation
total_rawAll tokens summedTrue total processed
Note

Cache reads are excluded from total_effective because they're significantly cheaper than other token types.

CLI Reference

Core Commands

CommandDescription
statusShow buffer statistics
report [-n limit] [--current]Show recent auto-captured metrics in table format
list [-n limit]List recent agent runs from session files
extract <id> [-f format] [-a agent-name]Extract metrics for a specific agent
compare <id...>Compare multiple agents side-by-side
find <id>Find the file location for an agent

Buffer Commands

CommandDescription
buffer statusShow buffer statistics
buffer list [-s session] [-a agent-name] [--since duration] [-f format]List buffered entries
buffer session <id> [-f format]Get all entries for a session
buffer clear --session <id>Clear entries for a session
buffer clear --agents <id...>Clear specific agent IDs
buffer clear --expiredGarbage collect expired entries

Log Commands

CommandDescription
log statusShow log file statistics
log tail [-n lines] [-f]View recent log entries (supports follow mode)
log clear [--all]Clear log file
log pathPrint log file path

Output Formats

JSON (default)

json
{
  "agent_id": "a80e24f",
  "model": "claude-sonnet-4-5-20250929",
  "duration_ms": 113126,
  "duration_formatted": "1m 53s",
  "tokens": {
    "input": 667,
    "output": 1510,
    "cache_creation": 63236,
    "cache_read": 315202,
    "total_effective": 65413,
    "total_raw": 380615
  },
  "execution": {
    "message_count": 30,
    "tool_use_count": 13,
    "tool_breakdown": { "Bash": 12, "Read": 1 },
    "error_count": 0
  }
}

Summary Format

bash
agent-metrics extract a80e24f --format summary

Human-readable output with boxed sections for identification, context, timing, tokens, execution, and tool breakdown.

Tracker Format

bash
agent-metrics extract a80e24f --format tracker --agent-name code-validator

Produces output ready for save_run:

json
{
  "name": "code-validator",
  "model": "claude-sonnet-4-5-20250929",
  "tokens": {
    "input_tokens": 63903,
    "output_tokens": 1510,
    "cache_creation_tokens": 63236,
    "cache_read_tokens": 315202,
    "total_effective_tokens": 65413
  },
  "duration_ms": 113126
}

Auto-Capture with SubagentStop Hook

The agent-metrics hook automatically captures metrics when any Task tool agent completes, writing them to a global buffer at ~/.claude/agent-metrics-buffer.jsonl.

Setup

Add the hook to ~/.claude/settings.json:

json
{
  "hooks": {
    "SubagentStop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "node ~/.claude/tools/agent-metrics/dist/hook.js",
            "timeout": 10
          }
        ]
      }
    ]
  }
}

Workflow Integration

After a multi-agent workflow, retrieve all agent metrics for the session:

bash
SESSION_ID="ea588859-88cd-4511-851a-4fe928cd77c7"

# Get all agents' metrics in tracker format
agent-metrics buffer session $SESSION_ID --format tracker

This returns an array of tracker-formatted metrics for every agent that ran in the session.

Programmatic API

Core Extraction

typescript
import {
  extractAgentMetrics,
  extractMetricsFromFile,
  extractMultipleAgentMetrics,
  formatMetricsSummary,
  toTrackerFormat,
} from '@uluops/agent-metrics';

// Extract by agent ID (searches all projects)
const metrics = await extractAgentMetrics('a80e24f');
if (metrics) {
  console.log(`Duration: ${metrics.duration_formatted}`);
  console.log(`Tokens: ${metrics.tokens.total_effective}`);
}

// Format as human-readable summary
const summary = formatMetricsSummary(metrics);

// Convert to validation tracker format
const trackerData = toTrackerFormat(metrics, 'code-validator');

Buffer Operations

typescript
import {
  queryBuffer,
  getAllForSession,
  getLatestForSession,
  getBufferStats,
  cleanupExpired,
} from '@uluops/agent-metrics';

// Query buffer with filters
const entries = queryBuffer({
  sessionId: 'ea588859-...',
  agentName: 'code-validator',
  since: new Date(Date.now() - 3600000),
});

// Get all entries for a session
const sessionEntries = getAllForSession('ea588859-...');

// Garbage collect
const expiredCount = cleanupExpired();

Utilities

typescript
import {
  findAgentFile,
  findRecentAgentFiles,
  formatDuration,
  formatTokens,
  formatModelName,
} from '@uluops/agent-metrics';

findAgentFile('a80e24f');           // { filePath, projectDir }
formatDuration(113126);             // "1m 53s"
formatTokens(65413);                // "65.4k"
formatModelName('claude-sonnet-4-5-20250929', 12); // "sonnet-4-5"

Types

typescript
import type {
  AgentMetrics,
  TokenMetrics,
  ExecutionMetrics,
  TrackerFormat,
  BufferEntry,
  LoggerConfig,
} from '@uluops/agent-metrics';