Skip to content

Instantly share code, notes, and snippets.

@pybe
Created January 21, 2026 13:56
Show Gist options
  • Select an option

  • Save pybe/c58232a9c1fc0d2811bea2fd9b8b4c9a to your computer and use it in GitHub Desktop.

Select an option

Save pybe/c58232a9c1fc0d2811bea2fd9b8b4c9a to your computer and use it in GitHub Desktop.
session-log: Pretty-print Claude Code JSONL session logs
#!/bin/bash
# session-log - Pretty-print Claude Code JSONL session logs
#
# Usage:
# session-log [OPTIONS] [FILE]
#
# Arguments:
# FILE Path to a Claude Code .jsonl session file
# If omitted, shows the most recent session
#
# Options:
# -h, --help Show this help message
# -l, --list List available session files
# -t, --tail N Show only last N entries (default: all)
#
# Examples:
# session-log # View latest session
# session-log -l # List all sessions
# session-log /path/to/file.jsonl # View specific session
# session-log -t 50 # Last 50 entries of latest
#
# Output Legend:
# ━━━ USER ━━━ Human input
# ━━━ ASSISTANT ━━━ Claude's text response
# ⚡ ToolName: Tool/command being executed
# 📥 RESULT: Tool output returned to Claude
# 💭 thinking... Claude's extended thinking
show_help() {
head -28 "$0" | tail -27 | sed 's/^# //' | sed 's/^#//'
exit 0
}
list_sessions() {
echo "Recent session files:"
ls -lt ~/.claude/projects/*/*.jsonl 2>/dev/null | head -20 | awk '{print " " $6, $7, $8, $9}'
exit 0
}
TAIL_COUNT=""
while [[ $# -gt 0 ]]; do
case $1 in
-h|--help) show_help ;;
-l|--list) list_sessions ;;
-t|--tail) TAIL_COUNT="$2"; shift 2 ;;
*) FILE="$1"; shift ;;
esac
done
if [ -z "$FILE" ]; then
FILE=$(ls -t ~/.claude/projects/*/*.jsonl 2>/dev/null | head -1)
if [ -z "$FILE" ]; then
echo "No session logs found"
exit 1
fi
echo "Showing: $FILE"
echo ""
fi
if [ ! -f "$FILE" ]; then
echo "File not found: $FILE"
exit 1
fi
if [ -n "$TAIL_COUNT" ]; then
INPUT="tail -$TAIL_COUNT \"$FILE\""
else
INPUT="cat \"$FILE\""
fi
eval $INPUT | jq -r '
if .type == "user" then
if (.message.content | type) == "array" and (.message.content[0].type? == "tool_result") then
"📥 RESULT: " + (.message.content[0].content | tostring)[0:150]
else
"\n━━━ USER ━━━\n" + (.message.content // "")
end
elif .type == "assistant" then
(.message.content[]? |
if .type == "text" then "\n━━━ ASSISTANT ━━━\n" + .text
elif .type == "tool_use" then "⚡ " + .name + ": " + (.input.command // .input.file_path // (.input | tostring))[0:100]
elif .type == "thinking" then "💭 thinking..."
else "" end)
else empty end' | less
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment