Install
$ agentstack add skill-karashiiro-agent-skills-analyzing-claude-sessions ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Analyzing Claude Code Session Logs
Extract insights from Claude Code session transcripts using jq. Session logs are JSONL files where each line is a message in the conversation.
Log Locations
| Log Type | Path | |----------|------| | Main session | ~/.claude/projects/{project-hash}/{session-id}.jsonl | | Subagent | ~/.claude/projects/{project-hash}/{session-id}/subagents/agent-{agent-id}.jsonl | | Tool results | ~/.claude/projects/{project-hash}/{session-id}/tool-results/ |
Find the most recent session:
ls -t ~/.claude/projects/*/*.jsonl | head -1
List subagents for a session:
ls ~/.claude/projects/{project-hash}/{session-id}/subagents/
Message Structure
Each JSONL line has this shape:
{
"type": "user|assistant|progress|system|file-history-snapshot",
"message": {
"role": "user|assistant",
"content": "string" | [{"type": "text|tool_use|tool_result", ...}],
"model": "claude-sonnet-4-5-...",
"usage": {"input_tokens": N, "output_tokens": N, ...},
"stop_reason": "end_turn|tool_use|..."
},
"timestamp": "ISO8601",
"uuid": "...",
"agentId": "...",
"sessionId": "..."
}
Assistant messages have content as an array of blocks:
{"type": "text", "text": "..."}— text output{"type": "tool_use", "name": "Read", "id": "toolu_...", "input": {...}}— tool call{"type": "tool_result", "tool_use_id": "toolu_...", "content": "...", "is_error": bool}— tool response
Shell Quoting Note
jq filters work fine inline as long as the file path is either a literal or expanded in the same && chain as the variable assignment. The select(.type == "tool_use") syntax with inner double quotes works correctly inside single-quoted jq filters.
For array content blocks, use the if type == "array" guard since user messages have string content:
jq -r '.message.content | if type == "array" then [.[] | select(.type == "tool_use") | .name] | .[] else empty end' session.jsonl
For loops over subagent files, assign the directory path first:
SUBS="path/to/subagents" && for f in "$SUBS"/agent-*.jsonl; do
jq -r '...' "$f"
done
Quick Reference: jq Recipes
Session Overview
# Message type distribution
jq -r '.type' session.jsonl | sort | uniq -c | sort -rn
# Time span
jq -r '.timestamp' session.jsonl | sed -n '1p;$p'
# Model used
jq -r '.message.model // empty' session.jsonl | sort -u
Tool Usage
# Tool call frequency
jq -r '.message.content[]? | select(.type == "tool_use") | .name' session.jsonl | sort | uniq -c | sort -rn
# What files were read
jq -r '.message.content[]? | select(.type == "tool_use" and .name == "Read") | .input.file_path' session.jsonl
# Bash commands run
jq -r '.message.content[]? | select(.type == "tool_use" and .name == "Bash") | .input.command' session.jsonl
# Files written
jq -r '.message.content[]? | select(.type == "tool_use" and .name == "Write") | .input.file_path' session.jsonl
# Tool errors
jq -r '.message.content[]? | select(.type == "tool_result" and .is_error == true) | .content[:200]' session.jsonl
Agent Dispatches (main session only)
# Subagent launch sequence
jq -r 'select(.message.content[]? | .type == "tool_use" and .name == "Agent") | "\(.timestamp) \(.message.content[] | select(.type == "tool_use" and .name == "Agent") | .input.description)"' session.jsonl
# Agent types used
jq -r '.message.content[]? | select(.type == "tool_use" and .name == "Agent") | .input.subagent_type' session.jsonl | sort | uniq -c | sort -rn
Token Usage
# Total output tokens
jq -r 'select(.type == "assistant") | .message.usage.output_tokens // 0' session.jsonl | paste -sd+ | bc
# Cache hit rate
jq -r 'select(.type == "assistant") | .message.usage | "\(.cache_read_input_tokens // 0) cached / \(.input_tokens // 0) total"' session.jsonl
Subagent Analysis
# Role and cost per subagent
SUBS="path/to/subagents" && for f in "$SUBS"/agent-*.jsonl; do
turns=$(wc -l /dev/null)
[ -n "$files" ] && echo "--- $(basename "$f") ---" && echo "$files"
done
# Token totals per subagent
SUBS="path/to/subagents" && for f in "$SUBS"/agent-*.jsonl; do
jq -r 'select(.type == "assistant") | [(.message.usage.input_tokens // 0), (.message.usage.cache_read_input_tokens // 0), (.message.usage.output_tokens // 0)] | @csv' "$f" | awk -F, -v name="$(basename "$f")" '{i+=$1; c+=$2; o+=$3} END{printf "%s: %d in (%d cached), %d out\n", name, i, c, o}'
done
Content Search
# Find messages containing a keyword
jq -r 'select(.message.content | tostring | test("keyword"; "i")) | "\(.timestamp) [\(.type)]"' session.jsonl
# Extract all assistant text blocks
jq -r 'select(.type == "assistant") | .message.content[]? | select(.type == "text") | .text' session.jsonl
# Find tool errors
jq -r '.message.content[]? | select(.type == "tool_result") | .content' session.jsonl | grep -i "error"
Analysis Workflows
Performance Audit
- Count total tool calls vs turns — high tool:turn ratio means parallel calls (good), low means sequential
- Check for redundant reads: same file path appearing multiple times
- Check for Bash doing what dedicated tools handle (cat/grep/head instead of Read/Grep)
- Look for retry loops: same tool called with same args multiple times
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: karashiiro
- Source: karashiiro/agent-skills
- License: Unlicense
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.