Agent Skills: Introspect

Analyze Claude Code session logs - extract thinking blocks, tool usage stats, error patterns, debug trajectories. Triggers on: introspect, session logs, trajectory, analyze sessions, what went wrong, tool usage, thinking blocks, session history, my reasoning, past sessions, what did I do.

UncategorizedID: 0xdarkmatter/claude-mods/introspect

Install this agent skill to your local

pnpm dlx add-skill https://github.com/0xDarkMatter/claude-mods/tree/HEAD/skills/introspect

Skill Files

Browse the full folder contents for introspect.

Download Skill

Loading file tree…

skills/introspect/SKILL.md

Skill Metadata

Name
introspect
Description
"Analyze Claude Code session logs - extract thinking blocks, tool usage stats, error patterns, debug trajectories. Triggers on: introspect, session logs, trajectory, analyze sessions, what went wrong, tool usage, thinking blocks, session history, my reasoning, past sessions, what did I do."

Introspect

Extract actionable intelligence from Claude Code session logs. Analyze tool usage, reasoning patterns, errors, and conversation flow to improve workflows and debug issues.

Log File Structure

~/.claude/
├── history.jsonl                              # Global: all user inputs across projects
├── projects/
│   └── {project-path}/                        # e.g., X--Dev-claude-mods/
│       ├── sessions-index.json                # Session metadata index
│       ├── {session-uuid}.jsonl               # Full session transcript
│       └── agent-{short-id}.jsonl             # Subagent transcripts

Project Path Encoding

Project paths use double-dash encoding: X:\Dev\claude-modsX--Dev-claude-mods

# Find project directory for current path
project_dir=$(pwd | sed 's/[:\\\/]/-/g' | sed 's/--*/-/g')
ls ~/.claude/projects/ | grep -i "${project_dir##*-}"

Entry Types in Session Files

| Type | Contains | Key Fields | |------|----------|------------| | user | User messages | message.content, uuid, timestamp | | assistant | Claude responses | message.content[], cwd, gitBranch | | thinking | Reasoning blocks | thinking, signature (in content array) | | tool_use | Tool invocations | name, input, id (in content array) | | tool_result | Tool outputs | tool_use_id, content | | summary | Conversation summaries | summary, leafUuid | | file-history-snapshot | File state checkpoints | File contents at point in time | | system | System context | Initial context, rules |

Core Analysis Patterns

List Sessions for Current Project

# Get sessions index
cat ~/.claude/projects/X--Dev-claude-mods/sessions-index.json | jq '.'

# List session files with sizes and dates
ls -lah ~/.claude/projects/X--Dev-claude-mods/*.jsonl | grep -v agent

Session Overview

SESSION="417ce03a-6fc7-4906-b767-6428338f34c3"
PROJECT="X--Dev-claude-mods"

# Entry type distribution
jq -r '.type' ~/.claude/projects/$PROJECT/$SESSION.jsonl | sort | uniq -c

# Session duration (first to last timestamp)
jq -s '[.[].timestamp // .[].message.timestamp | select(.)] | [min, max] | map(. / 1000 | strftime("%Y-%m-%d %H:%M"))' \
  ~/.claude/projects/$PROJECT/$SESSION.jsonl

# Conversation summaries (quick overview)
jq -r 'select(.type == "summary") | .summary' ~/.claude/projects/$PROJECT/$SESSION.jsonl

Tool Usage Statistics

PROJECT="X--Dev-claude-mods"

# Tool frequency across all sessions
cat ~/.claude/projects/$PROJECT/*.jsonl | \
  jq -r 'select(.type == "assistant") | .message.content[]? | select(.type == "tool_use") | .name' | \
  sort | uniq -c | sort -rn

# Tool frequency for specific session
jq -r 'select(.type == "assistant") | .message.content[]? | select(.type == "tool_use") | .name' \
  ~/.claude/projects/$PROJECT/$SESSION.jsonl | sort | uniq -c | sort -rn

# Tools with their inputs (sampled)
jq -c 'select(.type == "assistant") | .message.content[]? | select(.type == "tool_use") | {tool: .name, input: .input}' \
  ~/.claude/projects/$PROJECT/$SESSION.jsonl | head -20

Extract Thinking Blocks

SESSION="417ce03a-6fc7-4906-b767-6428338f34c3"
PROJECT="X--Dev-claude-mods"

# All thinking blocks (reasoning trace)
jq -r 'select(.type == "assistant") | .message.content[]? | select(.type == "thinking") | .thinking' \
  ~/.claude/projects/$PROJECT/$SESSION.jsonl

# Thinking blocks with context (which turn)
jq -r 'select(.type == "assistant") |
  .message.content as $content |
  ($content | map(select(.type == "thinking")) | .[0].thinking) as $thinking |
  ($content | map(select(.type == "text")) | .[0].text | .[0:100]) as $response |
  select($thinking) | "---\nThinking: \($thinking[0:500])...\nResponse: \($response)..."' \
  ~/.claude/projects/$PROJECT/$SESSION.jsonl

Error Analysis

PROJECT="X--Dev-claude-mods"

# Find tool errors across sessions
cat ~/.claude/projects/$PROJECT/*.jsonl | \
  jq -r 'select(.type == "user") | .message.content[]? | select(.type == "tool_result") |
    select(.content | test("error|Error|ERROR|failed|Failed|FAILED"; "i")) |
    {tool_id: .tool_use_id, error: .content[0:200]}' 2>/dev/null | head -50

# Count errors by pattern
cat ~/.claude/projects/$PROJECT/*.jsonl | \
  jq -r 'select(.type == "user") | .message.content[]? | select(.type == "tool_result") | .content' 2>/dev/null | \
  grep -i "error\|failed\|exception" | \
  sed 's/[0-9]\+//g' | sort | uniq -c | sort -rn | head -20

Search Across Sessions

PROJECT="X--Dev-claude-mods"

# Search user messages
cat ~/.claude/projects/$PROJECT/*.jsonl | \
  jq -r 'select(.type == "user") | .message.content[]? | select(.type == "text") | .text' | \
  grep -i "pattern"

# Search assistant responses
cat ~/.claude/projects/$PROJECT/*.jsonl | \
  jq -r 'select(.type == "assistant") | .message.content[]? | select(.type == "text") | .text' | \
  grep -i "pattern"

# Find sessions mentioning a file
for f in ~/.claude/projects/$PROJECT/*.jsonl; do
  if grep -q "specific-file.ts" "$f"; then
    echo "Found in: $(basename $f)"
  fi
done

Conversation Flow Reconstruction

SESSION="417ce03a-6fc7-4906-b767-6428338f34c3"
PROJECT="X--Dev-claude-mods"

# Reconstruct conversation (user/assistant turns)
jq -r '
  if .type == "user" then
    .message.content[]? | select(.type == "text") | "USER: \(.text[0:200])"
  elif .type == "assistant" then
    .message.content[]? | select(.type == "text") | "CLAUDE: \(.text[0:200])"
  else empty end
' ~/.claude/projects/$PROJECT/$SESSION.jsonl

Subagent Analysis

PROJECT="X--Dev-claude-mods"

# List subagent sessions
ls ~/.claude/projects/$PROJECT/agent-*.jsonl 2>/dev/null

# Subagent tool usage
for f in ~/.claude/projects/$PROJECT/agent-*.jsonl; do
  echo "=== $(basename $f) ==="
  jq -r 'select(.type == "assistant") | .message.content[]? | select(.type == "tool_use") | .name' "$f" | \
    sort | uniq -c | sort -rn | head -5
done

Advanced Analysis

Token/Cost Estimation

SESSION="417ce03a-6fc7-4906-b767-6428338f34c3"
PROJECT="X--Dev-claude-mods"

# Rough character count (tokens ≈ chars/4)
jq -r '[
  (select(.type == "user") | .message.content[]? | select(.type == "text") | .text | length),
  (select(.type == "assistant") | .message.content[]? | select(.type == "text") | .text | length)
] | add' ~/.claude/projects/$PROJECT/$SESSION.jsonl | \
  awk '{sum+=$1} END {print "Total chars:", sum, "Est tokens:", int(sum/4)}'

File Modification Tracking

SESSION="417ce03a-6fc7-4906-b767-6428338f34c3"
PROJECT="X--Dev-claude-mods"

# Files edited (Edit tool usage)
jq -r 'select(.type == "assistant") | .message.content[]? |
  select(.type == "tool_use" and .name == "Edit") | .input.file_path' \
  ~/.claude/projects/$PROJECT/$SESSION.jsonl | sort | uniq -c | sort -rn

# Files written
jq -r 'select(.type == "assistant") | .message.content[]? |
  select(.type == "tool_use" and .name == "Write") | .input.file_path' \
  ~/.claude/projects/$PROJECT/$SESSION.jsonl | sort | uniq

Session Comparison

PROJECT="X--Dev-claude-mods"
SESSION1="session-id-1"
SESSION2="session-id-2"

# Compare tool usage between sessions
echo "=== Session 1 ===" && \
jq -r 'select(.type == "assistant") | .message.content[]? | select(.type == "tool_use") | .name' \
  ~/.claude/projects/$PROJECT/$SESSION1.jsonl | sort | uniq -c | sort -rn

echo "=== Session 2 ===" && \
jq -r 'select(.type == "assistant") | .message.content[]? | select(.type == "tool_use") | .name' \
  ~/.claude/projects/$PROJECT/$SESSION2.jsonl | sort | uniq -c | sort -rn

Quick Reference Commands

| Task | Command Pattern | |------|-----------------| | List sessions | ls -lah ~/.claude/projects/$PROJECT/*.jsonl \| grep -v agent | | Entry types | jq -r '.type' $SESSION.jsonl \| sort \| uniq -c | | Tool stats | jq -r '... \| select(.type == "tool_use") \| .name' \| sort \| uniq -c | | Extract thinking | jq -r '... \| select(.type == "thinking") \| .thinking' | | Find errors | grep -i "error\|failed" $SESSION.jsonl | | Session summaries | jq -r 'select(.type == "summary") \| .summary' | | User messages | jq -r 'select(.type == "user") \| .message.content[]?.text' |

Usage Examples

"What tools did I use most in yesterday's session?"

# Find yesterday's sessions by modification time
find ~/.claude/projects/X--Dev-claude-mods -name "*.jsonl" -mtime -1 ! -name "agent-*" | \
  xargs -I{} jq -r 'select(.type == "assistant") | .message.content[]? | select(.type == "tool_use") | .name' {} | \
  sort | uniq -c | sort -rn

"Show me my reasoning when debugging the auth issue"

# Search for sessions mentioning auth, then extract thinking
for f in ~/.claude/projects/$PROJECT/*.jsonl; do
  if grep -qi "auth" "$f"; then
    echo "=== $(basename $f) ==="
    jq -r 'select(.type == "assistant") | .message.content[]? | select(.type == "thinking") | .thinking' "$f" | \
      grep -i -A5 -B5 "auth"
  fi
done

"What errors occurred most frequently this week?"

find ~/.claude/projects/ -name "*.jsonl" -mtime -7 | \
  xargs cat 2>/dev/null | \
  jq -r 'select(.type == "user") | .message.content[]? | select(.type == "tool_result") | .content' 2>/dev/null | \
  grep -i "error\|failed" | \
  sed 's/[0-9]\+//g' | sed 's/\/[^ ]*//g' | \
  sort | uniq -c | sort -rn | head -10

Privacy Considerations

Session logs contain:

  • Full conversation history including any sensitive data discussed
  • File contents that were read or written
  • Thinking/reasoning (internal deliberation)
  • Tool inputs/outputs

Before sharing session exports:

  1. Review for credentials, API keys, personal data
  2. Consider redacting file paths if they reveal project structure
  3. Thinking blocks may contain candid assessments

Export Formats

Markdown Report

SESSION="session-id"
PROJECT="X--Dev-claude-mods"

echo "# Session Report: $SESSION"
echo ""
echo "## Summary"
jq -r 'select(.type == "summary") | "- \(.summary)"' ~/.claude/projects/$PROJECT/$SESSION.jsonl
echo ""
echo "## Tool Usage"
jq -r 'select(.type == "assistant") | .message.content[]? | select(.type == "tool_use") | .name' \
  ~/.claude/projects/$PROJECT/$SESSION.jsonl | sort | uniq -c | sort -rn | \
  awk '{print "| " $2 " | " $1 " |"}'

JSON Export (for further processing)

jq -s '{
  session_id: "'$SESSION'",
  entries: length,
  tools: [.[] | select(.type == "assistant") | .message.content[]? | select(.type == "tool_use") | .name] | group_by(.) | map({tool: .[0], count: length}),
  summaries: [.[] | select(.type == "summary") | .summary]
}' ~/.claude/projects/$PROJECT/$SESSION.jsonl