Provides techniques to query, analyze, and extract insights from local Claude Code conversation logs.

Install

mkdir -p .claude/skills/cc-history && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/3579" && unzip -o skill.zip -d .claude/skills/cc-history && rm skill.zip

Installs to .claude/skills/cc-history

Activation

This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.

Reference documentation for analyzing Claude Code conversation history files
76 charsno explicit “when” trigger
Intermediate

Key capabilities

  • Parses local JSONL history files
  • Resolves project path directories
  • Filters messages by type
  • Extracts token usage metrics
  • Searches through assistant tool calls

How it works

It uses standard shell utilities like jq to traverse and format the structured JSONL logs created by the agent.

Inputs & outputs

You give it
Session search query
You get back
Parsed message objects or usage data

When to use cc-history

  • Search through past Claude Code sessions
  • Analyze token usage from history logs
  • Extract specific assistant responses
  • Debug historical agent tool results

About this skill

Claude Code History Analysis

Reference documentation for querying and analyzing Claude Code's conversation history. Use shell commands and jq to extract information from JSONL conversation files.

Directory Structure

~/.claude/projects/{encoded-path}/
  |-- {session-uuid}.jsonl          # Main conversation
  |-- {session-uuid}/
      |-- subagents/
      |   |-- agent-{hash}.jsonl    # Subagent conversations
      |-- tool-results/             # Large tool outputs

Project Path Resolution

Convert working directory to project directory:

PROJECT_DIR="~/.claude/projects/$(echo "$PWD" | sed 's|^/|-|; s|/\.|--|g; s|/|-|g')"

Encoding rules:

  • Leading / becomes -
  • Regular / becomes -
  • /. (hidden directory) becomes --

Examples:

  • /Users/bill/.claude -> -Users-bill--claude
  • /Users/bill/git/myproject -> -Users-bill-git-myproject

Message Types

TypeDescription
userUser input messages
assistantModel responses (thinking, tool_use, text)
systemSystem messages
queue-operationBackground task notifications (subagent done)

Message Structure

Each line in a JSONL file is a message object:

{
  "type": "assistant",
  "uuid": "abc123",
  "parentUuid": "xyz789",
  "timestamp": "2025-01-15T19:39:16.000Z",
  "sessionId": "session-uuid",
  "message": {
    "role": "assistant",
    "content": [...],
    "usage": {
      "input_tokens": 20000,
      "output_tokens": 500,
      "cache_read_input_tokens": 15000,
      "cache_creation_input_tokens": 5000
    }
  }
}

Assistant message content blocks:

  • type: "thinking" - Model thinking (has thinking field)
  • type: "tool_use" - Tool invocation (has name, input fields)
  • type: "text" - Text response (has text field)

Common Queries

Find Conversations

# List by modification time (most recent first)
ls -lt "$PROJECT_DIR"/*.jsonl

# Find by date
ls -la "$PROJECT_DIR"/*.jsonl | grep "Jan 15"

# Find by content
grep -l "search term" "$PROJECT_DIR"/*.jsonl

Extract Messages

# Get message by line number (1-indexed)
sed -n '42p' file.jsonl | jq .

# Get message by uuid
jq -c 'select(.uuid=="abc123")' file.jsonl

# All user messages
jq -c 'select(.type=="user")' file.jsonl

# All assistant messages
jq -c 'select(.type=="assistant")' file.jsonl

Tool Call Analysis

# List all tool calls
jq -c 'select(.type=="assistant") | .message.content[]? | select(.type=="tool_use") | {name, input}' file.jsonl

# Count tool calls by name
jq -c 'select(.type=="assistant") | .message.content[]? | select(.type=="tool_use") | .name' file.jsonl | sort | uniq -c | sort -rn

# Find specific tool calls
jq -c 'select(.type=="assistant") | .message.content[]? | select(.type=="tool_use" and .name=="Bash")' file.jsonl

Skill Invocation Detection

Pattern: python3 -m skills\.([a-z_]+)\.

# Find all skill invocations
grep -oE "python3 -m skills\.[a-z_]+" file.jsonl | sort -u

# Find conversations using a specific skill
grep -l "python3 -m skills\.planner\." "$PROJECT_DIR"/*.jsonl

Token Usage

# Total tokens in conversation
jq -s '[.[].message.usage? | select(.) | .input_tokens + .output_tokens] | add' file.jsonl

# Token breakdown
jq -s '[.[].message.usage? | select(.)] | {
  input: (map(.input_tokens) | add),
  output: (map(.output_tokens) | add),
  cached: (map(.cache_read_input_tokens // 0) | add)
}' file.jsonl

# Token progression over time
jq -c 'select(.type=="assistant") | {ts: .timestamp[11:19], inp: .message.usage.input_tokens, out: .message.usage.output_tokens}' file.jsonl

Taxonomy Aggregation

# Count messages by type
jq -s 'group_by(.type) | map({type: .[0].type, count: length})' file.jsonl

# Character count in user messages
jq -s '[.[] | select(.type=="user") | .message.content | length] | add' file.jsonl

# Thinking block character count
jq -s '[.[] | select(.type=="assistant") | .message.content[]? | select(.type=="thinking") | .thinking | length] | add' file.jsonl

Subagent Analysis

# List subagents for a session
ls "${SESSION_DIR}/subagents/"

# Get subagent task description (first user message)
jq -c 'select(.type=="user") | .message.content' agent-*.jsonl | head -1

# Find Task tool calls in parent (these spawn subagents)
jq -c 'select(.type=="assistant") | .message.content[]? | select(.type=="tool_use" and .name=="Task") | .input' file.jsonl

Conversation Branching

Each .jsonl file contains the entire conversation tree (all branches), not separate files per branch. Branching is tracked via parentUuid:

  • When user goes back in history and issues a new command, the new message gets the same parentUuid as where they branched from
  • Multiple messages sharing the same parentUuid = sibling branches (fork point)

Detecting Branch Points

# Find all fork points (messages with multiple children)
jq -s 'group_by(.parentUuid) | map(select(length > 1)) | .[] | {
  parentUuid: .[0].parentUuid,
  branches: length,
  timestamps: [.[].timestamp]
}' file.jsonl

# Show siblings at a known fork point
FORK_POINT="parent-uuid-here"
jq -c --arg fp "$FORK_POINT" 'select(.parentUuid==$fp) | {uuid, ts: .timestamp, preview: (.message.content | tostring)[:100]}' file.jsonl

Extracting a Single Branch

To filter for exactly one branch, find a unique identifier in that branch, then walk the ancestor chain back to root.

Step 1: Find target message uuid

# By unique content
TARGET=$(jq -r 'select(.message.content | tostring | contains("unique-identifier")) | .uuid' file.jsonl | tail -1)

# By timestamp prefix
TARGET=$(jq -r 'select(.timestamp | startswith("2026-01-28T11:23")) | .uuid' file.jsonl | head -1)

Step 2: Extract branch as JSONL stream

# Outputs one message per line (JSONL), oldest first
extract_branch() {
  jq -c -s --arg target "$1" '
    (map({(.uuid): .}) | add) as $lookup |
    {chain: [], current: $target} |
    until(.current == null or ($lookup[.current] | not);
      ($lookup[.current]) as $msg |
      .chain += [$msg] |
      .current = $msg.parentUuid
    ) |
    .chain | reverse | .[]
  ' "$2"
}

# Usage: extract_branch <target-uuid> <file>
extract_branch "$TARGET" file.jsonl | jq -s 'length'
extract_branch "$TARGET" file.jsonl | jq 'select(.type=="user")'

Step 3: Common branch queries

# Message count
extract_branch "$TARGET" file.jsonl | jq -s 'length'

# User messages only
extract_branch "$TARGET" file.jsonl | jq 'select(.type=="user")'

# Tool calls
extract_branch "$TARGET" file.jsonl | jq 'select(.type=="assistant") | .message.content[]? | select(.type=="tool_use") | {name}'

# First and last messages (verify correct branch)
extract_branch "$TARGET" file.jsonl | jq -s '[.[0], .[-1]] | .[] | {type, ts: .timestamp}'

Workflow: Pinpoint and Explore

# 1. Find conversation file
FILE=$(grep -l "unique-identifier" "$PROJECT_DIR"/*.jsonl)

# 2. Find matching messages (may show multiple branches)
jq -c 'select(.message.content | tostring | contains("unique-identifier")) | {uuid, ts: .timestamp, parentUuid}' "$FILE"

# 3. Pick target uuid from desired branch, then query
TARGET="uuid-from-step-2"
extract_branch "$TARGET" "$FILE" | jq 'select(.type=="user") | .message.content'

Correlation

Subagent files (agent-{hash}.jsonl) don't link directly to parent Task calls. To correlate:

  1. List all subagent files under {session}/subagents/
  2. Read first user message of each for task description
  3. Match description to Task tool_use blocks in parent conversation

When not to use it

  • For real-time conversation manipulation
  • When working outside of local session logs

Prerequisites

jqShell access

Limitations

  • Dependent on internal storage path conventions
  • JSONL files must be locally available

How it compares

It enables forensic analysis of agent memory instead of standard terminal command logging.

Compared to similar skills

cc-history side by side with the closest alternatives in the catalog.

SkillInstallsUpdatedSafetyDifficulty
cc-history (this skill)16moReviewIntermediate
vibe-sunsang-growth01moReviewIntermediate
q06moReviewBeginner
weread-skills02moReviewBeginner

Try saying

Example prompts that trigger this skill in your AI assistant.

You might also like

vibe-sunsang-growth

fivetaku

Growth report generator — analyzes AI-collaboration session data and produces a progression report using the v2 level system (6 axes × 7 levels, 0.5 increments). Korean triggers: "성장 리포트", "성장 분석", "얼마나 성장했는지", "레벨 체크", "성장 트래킹". English triggers: "growth report", "growth tracking", "level check".

00

q

DavidROliverBA

Fast SQLite-based vault search using FTS5 full-text search index

00

weread-skills

Tencent

微信读书助手 — 搜索书籍、管理书架、查看笔记划线、浏览书评、阅读统计、发现推荐好书

00

session-export

CauchyIO

Export a project's Claude Code sessions into a readable transcript dump (the input the project-timeline skill needs). Walks the user through choosing the project, scoping which sessions to include (date window, excluding meta/plugin runs), and warns about secrets before writing. Use when the user wa

00

quant-analyst

zenobi-us

Expert quantitative analyst specializing in financial modeling, algorithmic trading, and risk analytics. Masters statistical methods, derivatives pricing, and high-frequency trading with focus on mathematical rigor, performance optimization, and profitable strategy development.

103355

stock-analyzer

FrancyJGLisboa

Provides comprehensive technical analysis for stocks and ETFs using RSI, MACD, Bollinger Bands, and other indicators. Activates when user requests stock analysis, technical indicators, trading signals, or market data for specific ticker symbols.

71214

Search skills

Search the agent skills registry