
Rg History
- 12 installs
- 54 repo stars
- Updated December 20, 2025
- backnotprop/rg_history
rg_history is a Claude skill that searches the current session's JSONL conversation history using ripgrep.
About
rg_history searches the assistant's own session history using ripgrep over the JSONL session log. It teaches a broad-to-narrow strategy (count matches, extract short snippets, then filter) so the raw JSON does not overwhelm the context, and documents the JSONL structure and file locations. A developer uses it to find previous messages, file edits, tool calls, or decisions from earlier in the session.
- Searches the current session's conversation history with ripgrep
- Uses a count-then-snippet-then-narrow strategy to avoid dumping walls of JSON
- Locates prior messages, file edits, tool calls, and decisions in the JSONL session log
Rg History by the numbers
- 12 all-time installs (skills.sh)
- Ranked #383 of 550 CLI & Terminal skills by installs in the Skillselion catalog
- Data as of Jul 28, 2026 (Skillselion catalog sync)
rg_history capabilities & compatibility
- Capabilities
- memory
- Use cases
- research · memory
- Platforms
- macOS · Linux
What rg_history says it does
Search your conversation history using ripgrep. Use when you need to find previous messages, file edits, tool calls, or decisions from earlier in the session.
Each event is one long JSON line. Full output will overwhelm you. Always start broad with limited output, then narrow in.
npx skills add https://github.com/backnotprop/rg_history --skill rg_historyAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 12 |
|---|---|
| repo stars | ★ 54 |
| Last updated | December 20, 2025 |
| Repository | backnotprop/rg_history ↗ |
What it does
Search the current session's JSONL history with ripgrep to recover earlier messages, edits, and decisions.
Who is it for?
Recovering earlier context from the session log without flooding the window
When should I use this skill?
You need to find previous messages, file edits, tool calls, or decisions from earlier in the session.
What you get
Earlier messages, edits, tool calls, and decisions are found via bounded ripgrep snippets.
By the numbers
- four-step search pattern (count, snippet, narrow, full context)
Files
rg_history
Search your session history with ripgrep.
CRITICAL: Search Strategy
Each event is one long JSON line. Full output will overwhelm you. Always start broad with limited output, then narrow in.
The Pattern
# 1. COUNT first - how many matches?
rg -c 'search_term' session.jsonl
# 2. SNIPPETS - get context around matches (not full lines)
rg -o '.{0,60}search_term.{0,60}' session.jsonl | head -20
# 3. NARROW - pipe to filter further
rg -o '.{0,60}search_term.{0,60}' session.jsonl | rg 'new_string'
# 4. FULL CONTEXT - only when you know what you want
rg '"name":"Edit".*search_term' session.jsonl -M 500Never run raw `rg 'pattern' file.jsonl` - you'll get walls of JSON.
Always use one of:
-cto count matches-o '.{0,60}pattern.{0,60}'for snippets-M 200to truncate lines| head -20to limit results
---
Find Your Session Files
Run the helper script:
scripts/list-sessions.sh /path/to/project # defaults to cwdOr construct manually:
~/.claude/projects/{encoded_project_path}/{session_id}.jsonlWhere encoded_project_path = project path with / replaced by -.
File Structure
~/.claude/projects/-Users-ramos-my-project/
├── abc123-def4-5678-....jsonl # Main session (UUID format)
├── agent-a1b2c3d.jsonl # Sub-agent spawned by Task tool
└── ...- Main session: Full UUID, your conversation
- Agent files:
agent-{7-char-id}.jsonl, from Task tool - Agent IDs appear in results as
"agentId": "a1b2c3d"
---
JSONL Structure Reference
Each line is one JSON object. Key fields:
Message types:
"type":"user"+"userType":"external"= actual human input"type":"assistant"= Claude's responses"type":"tool_result"= tool output
Tool calls (in assistant messages):
"name":"Edit"→"input":{"file_path":"...", "old_string":"...", "new_string":"..."}"name":"Write"→"input":{"file_path":"...", "content":"..."}"name":"Bash"→"input":{"command":"..."}"name":"Task"→"input":{"prompt":"...", "subagent_type":"..."}
Content blocks:
"type":"text"- message text"type":"thinking"- Claude's reasoning"type":"tool_use"- tool invocation
Other fields:
"timestamp":"2025-12-20T..."- when it happened"agentId":"..."- links to agent file"isCompactSummary":true- compacted context
---
Example Search Patterns
Remember: always use snippets or limit output!
# Find human messages (not tool results)
rg -o '.{0,40}"userType":"external".{0,40}' session.jsonl | head -10
# Find file edits
rg -c '"name":"Edit"' session.jsonl # count first
rg -o '.{0,50}"name":"Edit".{0,50}' session.jsonl | head -10
# Find edits to specific file
rg -o '.{0,30}auth.{0,30}' session.jsonl | rg 'file_path'
# Find commands that were run
rg -o '.{0,80}"command":".{0,80}' session.jsonl | head -10
# Find code in file writes
rg -o '.{0,60}function.{0,60}' session.jsonl | rg 'new_string\|content'---
Quick Reference
| Goal | Command |
|---|---|
| Count matches | rg -c 'pattern' file |
| Snippets | rg -o '.{0,60}pattern.{0,60}' file |
| Limit output | `\ |
| Truncate lines | -M 200 |
| Case insensitive | -i |
| Chain filters | `rg 'a' \ |
#!/bin/bash
# List Claude Code session files for a project
# Usage: list-sessions.sh [project-path]
# If no project path given, uses current directory
set -e
# Get project path (default to CWD)
PROJECT_PATH="${1:-$(pwd)}"
# Encode project path: /Users/foo/bar -> -Users-foo-bar
ENCODED_PATH=$(echo "$PROJECT_PATH" | sed 's|/|-|g')
# Session directory
SESSION_DIR="$HOME/.claude/projects/$ENCODED_PATH"
if [ ! -d "$SESSION_DIR" ]; then
echo "error: No session directory found for $PROJECT_PATH" >&2
echo " Expected: $SESSION_DIR" >&2
exit 1
fi
echo "Session directory: $SESSION_DIR"
echo ""
# List main sessions (UUID format, sorted by modification time, newest first)
echo "Sessions (newest first):"
for file in $(ls -t "$SESSION_DIR"/*.jsonl 2>/dev/null); do
filename=$(basename "$file" .jsonl)
# Skip agent files
if [[ "$filename" == agent-* ]]; then
continue
fi
size=$(ls -lh "$file" | awk '{print $5}')
modified=$(stat -f "%Sm" -t "%Y-%m-%d %H:%M" "$file" 2>/dev/null || stat -c "%y" "$file" 2>/dev/null | cut -d'.' -f1)
echo " $filename ($size, $modified)"
done
echo ""
# List agent files
AGENT_COUNT=$(ls "$SESSION_DIR"/agent-*.jsonl 2>/dev/null | wc -l | tr -d ' ')
if [ "$AGENT_COUNT" -gt 0 ]; then
echo "Agent files ($AGENT_COUNT):"
ls -t "$SESSION_DIR"/agent-*.jsonl 2>/dev/null | while read -r file; do
filename=$(basename "$file")
size=$(ls -lh "$file" | awk '{print $5}')
echo " $filename ($size)"
done
else
echo "Agent files: none"
fi
echo ""
echo "To search:"
echo " rg 'pattern' $SESSION_DIR/<session-id>.jsonl"
echo " rg 'pattern' $SESSION_DIR/agent-*.jsonl # all agents"