/session-insights — Extract insights from past sessions
Parse .jsonl session transcripts and extract structured insights: problems, decisions, patterns, friction points. Works on sessions outside the current context.
Step 1: Find sessions
Resolve memory directory, then find sessions by argument:
GIT_ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd)
PROJ_KEY=$(echo "$GIT_ROOT" | tr '/.' '-' | sed 's/^-//')
SESSIONS_DIR="$HOME/.claude/projects/-${PROJ_KEY}/"
- Ticket/keyword — grep across all
.jsonlfiles - Session ID — specific file by UUID
- Workstream — use
node "$MEM" --dir="$MEM_DIR" workstream <name>for context, match by dates/keywords - No argument — most recent session
grep -l "<query>" "$SESSIONS_DIR"*.jsonl 2>/dev/null | head -10
Also check session index if available:
cat "$MEM_DIR/sessions.jsonl" 2>/dev/null
Step 2: Extract user messages
For each session found:
import json, sys
with open(sys.argv[1]) as f:
for i, line in enumerate(f):
try:
obj = json.loads(line.strip())
if obj.get('type') != 'user':
continue
c = obj.get('message', {}).get('content', obj.get('content', ''))
if isinstance(c, list):
for item in c:
if isinstance(item, dict) and item.get('type') == 'text':
text = item.get('text', '').strip()
if text and not text.startswith('<') and len(text) > 5:
print(text[:300])
elif isinstance(c, str):
text = c.strip()
if text and not text.startswith('<') and len(text) > 5:
print(text[:300])
except:
pass
Step 3: Analyze
Extract structured insights from the user messages:
- Problems — what didn't work, was redone, caused friction
- Decisions — what was chosen and why (architectural, process)
- Insights — non-obvious conclusions, patterns, reassessments
- Friction points — where the agent repeatedly failed, what required many iterations
Format:
## Session insights: <date range or session id>
### Problems
- <description> → <resolution or status>
### Decisions
- <what> — <why>
### Insights
- <insight> — <evidence from session>
### Friction
- <what> (×N iterations) — <root cause>
Step 4: Save
MUST present all options as a numbered menu and wait for user response before writing anything:
What to do with these insights?
1. Save insights to memory (feedback/ or decisions/)
2. Add friction points to backlog
3. Mark as DOC: for /docs-reflect
4. Skip — display only
Choose (1-4, or comma-separated):
Then execute only what the user chose.
Rules
- Filter system messages, ide_opened_file, tool calls — only USER text
- Large sessions (>50KB user text) — split into chunks
- Don't dump raw output — format into readable blocks
- If multiple sessions found for a query — combine chronologically
- If session index (
sessions.jsonl) exists — use it for faster lookup