| name | transcript-intelligence |
| description | Search and analyze Claude Code transcripts for past decisions, solutions, and discussions. Use when recalling past context, finding solutions to previously-solved problems, understanding session history, or restoring context after compact/clear. |
| allowed-tools | ["Read","Bash","Glob","Grep"] |
Transcript Intelligence
Search, analyze, and extract knowledge from Claude Code session transcripts - your deep memory for past conversations, decisions, and solutions.
Quick Reference
| Element | Value |
|---|
| Transcript Location | ~/.claude/projects/<project-hash>/<session-id>.jsonl |
| Format | JSONL (one JSON object per line) |
| Line Types | user, assistant, system, summary, file-history-snapshot |
| Key Tools | rg (ripgrep), jq, Grep, Read, sesh |
| Integration | Works with /recall command and sesh CLI |
Using sesh for Easy Access
The sesh CLI provides human-friendly access to transcripts by session name:
sesh transcript my-session
cat $(sesh transcript my-session)
rg "keyword" $(sesh transcript my-session)
cat $(sesh transcript my-session) | jq 'select(.type == "user")'
sesh info my-session
sesh list --project .
sesh list --limit 10
Benefits Over Manual Path Navigation
| Manual Approach | With sesh |
|---|
ls ~/.claude/projects/ to find hash | sesh list to see all sessions |
| Remember session UUIDs | Use memorable names like "auth-feature" |
| Navigate nested directories | sesh transcript <name> returns path |
| Search across unknown paths | sesh list --project /path filters by project |
Transcript Location
Transcripts are stored in project-specific directories:
~/.claude/projects/
├── <project-hash-1>/
│ ├── <session-id-1>.jsonl
│ ├── <session-id-2>.jsonl
│ └── ...
├── <project-hash-2>/
│ └── ...
└── ...
Finding Your Project's Transcripts
Using sesh (recommended):
sesh list --project .
sesh transcript my-session
sesh info my-session
Manual approach:
ls -la ~/.claude/projects/
ls -lt ~/.claude/projects/*/ | head -20
find ~/.claude/projects -name "*.jsonl" -mtime -7
Transcript Line Structure
Each line is a JSON object:
interface TranscriptLine {
type: 'user' | 'assistant' | 'file-history-snapshot' | 'system' | 'summary';
uuid: string;
parentUuid: string | null;
sessionId: string;
timestamp: string;
cwd: string;
version: string;
gitBranch?: string;
message: {
role: 'user' | 'assistant';
content: ContentBlock[] | string;
model?: string;
usage?: {
input_tokens: number;
output_tokens: number;
};
};
toolUseResult?: any;
}
Content Block Types
The message.content field can contain:
| Type | Description |
|---|
text | Plain text content |
tool_use | Claude invoking a tool |
tool_result | Result from tool execution |
thinking | Claude's reasoning (extended thinking) |
Common Search Patterns
Search for Decisions
rg -i "decided|decision|chose|choice" ~/.claude/projects/<hash>/*.jsonl
rg -i "architecture|design|pattern" ~/.claude/projects/<hash>/*.jsonl
rg -i "tradeoff|trade-off|pros and cons|alternative" ~/.claude/projects/<hash>/*.jsonl
Search for Solutions
rg -i "fixed|resolved|solution|workaround" ~/.claude/projects/<hash>/*.jsonl
rg "error|exception|failed" ~/.claude/projects/<hash>/*.jsonl | rg -i "<error-text>"
rg -i "implemented|implementation|approach" ~/.claude/projects/<hash>/*.jsonl
Search by Time
find ~/.claude/projects -name "*.jsonl" -mtime -1
cat transcript.jsonl | jq -r 'select(.timestamp >= "2025-01-01" and .timestamp < "2025-01-07")'
Search User Messages Only
cat transcript.jsonl | jq -r 'select(.type == "user") | .message.content'
cat transcript.jsonl | jq -r 'select(.type == "user") | .message.content' | rg -i "keyword"
Search Assistant Responses Only
cat transcript.jsonl | jq -r 'select(.type == "assistant") | .message.content[] | select(.type == "text") | .text'
cat transcript.jsonl | jq -r 'select(.type == "assistant") | .message.content[] | select(.type == "text") | .text' | rg -i "keyword"
Use Cases
1. Context Restoration After Compact
When context is compacted or cleared, search transcripts to restore important information:
rg -C 3 "important|critical|remember|note" $(sesh transcript my-session)
cat $(sesh transcript my-session) | jq '.message.content[] | select(.type == "tool_use" and (.name == "Write" or .name == "Edit"))'
rg -C 3 "important|critical|remember|note" <transcript>.jsonl
2. Finding Past Solutions
Recall how you solved similar problems:
rg -l "TypeError" ~/.claude/projects/<hash>/*.jsonl
rg -C 5 "TypeError" <transcript>.jsonl
3. Session Analytics
Understand usage patterns:
wc -l ~/.claude/projects/<hash>/*.jsonl
cat transcript.jsonl | jq -r 'select(.message.usage) | .message.usage | "\(.input_tokens) in, \(.output_tokens) out"'
cat transcript.jsonl | jq -s '[.[].message.usage | select(.) | .input_tokens + .output_tokens] | add'
4. Finding Specific Tool Uses
cat transcript.jsonl | jq 'select(.type == "assistant") | .message.content[] | select(.type == "tool_use" and .name == "Write")'
cat transcript.jsonl | jq 'select(.type == "assistant") | .message.content[] | select(.type == "tool_use" and .name == "Bash") | .input.command'
cat transcript.jsonl | jq 'select(.type == "assistant") | .message.content[] | select(.type == "tool_use" and .name == "Read") | .input.file_path'
5. Reconstructing Conversation Flow
cat transcript.jsonl | jq -r '[.timestamp, .type, (if .type == "user" then .message.content else (.message.content[] | select(.type == "text") | .text[:100]) end)] | @tsv'
cat transcript.jsonl | jq -r 'select(.type == "user" or .type == "assistant") | "\(.type): \(if .message.content | type == "string" then .message.content else (.message.content[] | select(.type == "text") | .text[:200]) end)"'
Integration with /recall Command
This skill works alongside the /recall command for structured memory retrieval:
/recall "what did we decide about the API design?"
When invoked via /recall:
- Identify relevant project hash
- Search across all session transcripts
- Extract relevant context with surrounding lines
- Summarize findings
Workflow: Deep Memory Search
Prerequisites
Steps (Using sesh - Recommended)
-
List available sessions
-
Search by session name
-
Get context around matches
-
Extract structured data
-
Summarize findings
Steps (Manual - Without sesh)
-
Identify project directory
-
Perform broad search
-
Narrow to specific session
-
Extract structured data
-
Summarize findings
Validation
Performance Tips
| Scenario | Recommendation |
|---|
| Large transcripts | Use rg -l first to find files, then search specific ones |
| Many sessions | Narrow by date with find -mtime |
| Complex queries | Pipe through jq for structured filtering |
| Slow searches | Limit with head or -m (max matches) |
Common jq Patterns
cat transcript.jsonl | jq 'select(.type == "user")'
cat transcript.jsonl | jq -r '.timestamp'
cat transcript.jsonl | jq -r '.message.model // empty' | sort -u
cat transcript.jsonl | jq -r '.type' | sort | uniq -c
cat transcript.jsonl | jq -r '.gitBranch // empty' | sort -u
Troubleshooting
| Issue | Solution |
|---|
| No transcripts found | Check ~/.claude/projects/ exists and has subdirectories |
| Empty results | Try broader search terms, check project hash |
| jq errors | Ensure each line is valid JSON (some may be malformed) |
| Slow searches | Use file-level filtering first (rg -l), then content search |
| Can't find project | Look at recent modification times, or search all projects |
| sesh returns "no transcript path" | Session was created before transcript tracking was enabled |
| sesh session not found | Check sesh list to see available session names |
| Need to search older sessions | Use sesh list --all-machines to see sessions from all machines |
Security Notes
- Transcripts may contain sensitive information
- Avoid searching for/exposing secrets, API keys, passwords
- Be cautious when sharing transcript excerpts
- Transcripts are local to your machine
Hook Event Integration
When the event-logger hook handler is enabled, hook events are logged to ~/.claude/hooks/ and can be indexed alongside transcripts for unified analysis.
Enabling Hook Event Logging
Add to your hooks.yaml:
builtins:
event-logger:
enabled: true
Unified Index
The transcript CLI indexes both transcripts and hook events:
bun run bin/transcript.ts index build
bun run bin/transcript.ts index status
bun run bin/transcript.ts index daemon start
SQL JOINs
Query across transcripts and hook events:
SELECT h.toolName, h.decision, l.content_text
FROM hook_events h
JOIN lines l ON h.session_id = l.session_id AND h.tool_use_id = l.uuid
WHERE h.decision = 'block';
See TYPES.md for complete hook event schema and JOIN patterns.
Reference Files
| File | Contents |
|---|
| TYPES.md | Complete TypeScript type definitions (includes hook events) |
| SEARCH.md | Advanced search patterns and queries |