# Session Parsing & Insights Guide **Parse Claude Code sessions and extract insights automatically.** --- ## Overview Claude Code stores conversation history in `.jsonl` session files located at: ``` ~/.claude/projects/{encoded-project-path}/{session-id}.jsonl ``` Claude OS can parse these files to: - Extract conversations, tool calls, and file changes - Generate summaries for context loading - Extract insights (patterns, decisions, blockers) - Build analytics on your development sessions --- ## Session File Format Claude Code session files are JSON Lines format with various entry types: ```jsonl {"type": "summary", "summary": "...", "leafUuid": "..."} {"type": "user", "uuid": "msg-001", "message": {"role": "user", "content": "..."}} {"type": "assistant", "uuid": "msg-002", "message": {"role": "assistant", "content": [...]}} {"type": "file-history-snapshot", "messageId": "...", "snapshot": {...}} ``` ### Entry Types | Type | Description | |------|-------------| | `summary` | Session summary (usually at start) | | `user` | User message | | `assistant` | Assistant response (may contain tool_use) | | `file-history-snapshot` | File changes made during session | --- ## Using the Session Parser ### Python API ```python from app.core.session_parser import ( SessionParser, get_project_sessions_dir, list_session_files ) # Find sessions for a project project_path = "/Users/me/Projects/myapp" sessions = list_session_files(project_path) # Returns: ['/path/to/session1.jsonl', '/path/to/session2.jsonl'] # Parse a session parser = SessionParser(sessions[0]) session_data = parser.parse() # Access parsed data print(f"Session ID: {session_data.session_id}") print(f"Messages: {len(session_data.messages)}") print(f"Tool Calls: {len(session_data.tool_calls)}") print(f"File Changes: {len(session_data.file_changes)}") print(f"Duration: {session_data.start_time} to {session_data.end_time}") # Get conversation messages messages = parser.get_conversation() for msg in messages: print(f"{msg.role}: {msg.content[:100]}...") # Get summary for LLM processing summary = parser.get_summary_for_extraction(max_tokens=500) print(summary) ``` ### REST API ```bash # List sessions for a project curl "http://localhost:8051/api/sessions?project_path=/path/to/project&limit=10" # Get session details curl "http://localhost:8051/api/sessions/abc123?project_path=/path/to/project" # Get session summary curl "http://localhost:8051/api/sessions/abc123/summary?project_path=/path/to/project&max_tokens=500" ``` --- ## Session Data Structure ### SessionData ```python @dataclass class SessionData: session_id: str session_path: str messages: List[Message] tool_calls: List[ToolCall] file_changes: List[FileChange] start_time: Optional[str] end_time: Optional[str] git_branch: Optional[str] cwd: Optional[str] total_entries: int ``` ### Message ```python @dataclass class Message: role: str # "user" or "assistant" content: str # Message content timestamp: str # ISO timestamp uuid: str # Message UUID parent_uuid: Optional[str] ``` ### ToolCall ```python @dataclass class ToolCall: tool_name: str # e.g., "Read", "Write", "Bash" timestamp: str uuid: str parent_uuid: Optional[str] input_data: Dict # Tool input parameters ``` ### FileChange ```python @dataclass class FileChange: file_path: str timestamp: str message_id: str # Which message triggered this change ``` --- ## Insight Extraction The InsightExtractor analyzes sessions to identify: - **Patterns** - Recurring solutions and approaches - **Decisions** - Architecture and implementation choices - **Blockers** - Problems encountered and how they were resolved - **Discoveries** - New learnings about the codebase ### Using InsightExtractor ```python from app.core.insight_extractor import InsightExtractor, Insight # Create extractor with Ollama extractor = InsightExtractor( ollama_host="http://localhost:11434", model="llama3.1:8b" ) # Extract insights from a session parser = SessionParser("/path/to/session.jsonl") summary = parser.get_summary_for_extraction(max_tokens=1000) insights = await extractor.extract_insights(summary) for insight in insights: print(f"Type: {insight.insight_type}") print(f"Title: {insight.title}") print(f"Content: {insight.content}") print(f"Tags: {insight.tags}") print("---") ``` ### Insight Types | Type | Description | |------|-------------| | `pattern` | A reusable solution or approach | | `decision` | An architectural or implementation choice | | `blocker` | A problem that was encountered | | `discovery` | Something new learned about the codebase | ### Saving Insights to Memory ```python from app.core.sqlite_manager import get_sqlite_manager db = get_sqlite_manager() for insight in insights: # Save to project memories KB db.add_document( kb_name=f"{project_name}-project_memories", content=f"# {insight.title}\n\n{insight.content}", filename=f"insight-{insight.insight_type}-{timestamp}.md", metadata={ "type": insight.insight_type, "tags": insight.tags, "session_id": session_data.session_id } ) ``` --- ## Session Summary Format The `get_summary_for_extraction()` method generates a structured summary: ``` # Session: abc123 Project: /Users/me/Projects/myapp Branch: feature-auth Duration: 2025-12-11T10:00:00Z to 2025-12-11T11:30:00Z ## Conversation (24 messages) USER: Help me implement user authentication... ASSISTANT: I'll help you implement authentication. Let me start by... USER: Can you add password hashing? ASSISTANT: Of course! I'll use bcrypt for secure password hashing... ## Tool Calls - Read: /Users/me/Projects/myapp/src/auth.py - Write: /Users/me/Projects/myapp/src/auth.py - Read: /Users/me/Projects/myapp/tests/test_auth.py - Write: /Users/me/Projects/myapp/tests/test_auth.py - Bash: pytest tests/test_auth.py ## File Changes - /Users/me/Projects/myapp/src/auth.py - /Users/me/Projects/myapp/tests/test_auth.py ``` --- ## Project Sessions Directory Claude Code encodes project paths for the sessions directory: ``` /Users/me/Projects/myapp → ~/.claude/projects/-Users-me-Projects-myapp/ ``` The encoding: 1. Replaces `/` with `-` 2. Keeps the leading `-` (from the initial `/`) ### Finding Sessions ```python from app.core.session_parser import get_project_sessions_dir, list_session_files # Get sessions directory for a project sessions_dir = get_project_sessions_dir("/Users/me/Projects/myapp") # Returns: ~/.claude/projects/-Users-me-Projects-myapp # List all session files sessions = list_session_files("/Users/me/Projects/myapp") # Returns sorted list of .jsonl files (newest first) ``` --- ## Use Cases ### 1. Load Context at Session Start ```python # At session start, load recent session insights sessions = list_session_files(project_path) if sessions: parser = SessionParser(sessions[0]) summary = parser.get_summary_for_extraction(max_tokens=500) # Use summary to prime Claude with recent context ``` ### 2. Build Session Analytics ```python # Analyze all sessions for a project sessions = list_session_files(project_path) stats = { "total_sessions": len(sessions), "total_messages": 0, "total_tool_calls": 0, "tools_used": {} } for session_path in sessions: parser = SessionParser(session_path) data = parser.parse() stats["total_messages"] += len(data.messages) stats["total_tool_calls"] += len(data.tool_calls) for tc in data.tool_calls: stats["tools_used"][tc.tool_name] = \ stats["tools_used"].get(tc.tool_name, 0) + 1 ``` ### 3. Extract and Save Patterns ```python # Extract insights from recent sessions extractor = InsightExtractor() for session_path in sessions[:5]: # Last 5 sessions parser = SessionParser(session_path) summary = parser.get_summary_for_extraction() insights = await extractor.extract_insights(summary) for insight in insights: if insight.insight_type == "pattern": # Save to memories KB save_to_memories(project_name, insight) ``` ### 4. Debug Failed Sessions ```python # Find sessions with errors for session_path in sessions: parser = SessionParser(session_path) data = parser.parse() # Look for error patterns in messages for msg in data.messages: if "error" in msg.content.lower() or "failed" in msg.content.lower(): print(f"Session {data.session_id} may have errors") print(f" Message: {msg.content[:100]}...") break ``` --- ## Configuration ### Environment Variables ```bash # Ollama settings for insight extraction OLLAMA_HOST=http://localhost:11434 OLLAMA_MODEL=llama3.1:8b ``` ### Truncation Settings Large sessions are automatically truncated for LLM processing: ```python # Default: 500 tokens (~2000 chars) summary = parser.get_summary_for_extraction(max_tokens=500) # For more context summary = parser.get_summary_for_extraction(max_tokens=2000) ``` --- ## Troubleshooting ### "No sessions found" - Verify project path is correct - Check that sessions exist: `ls ~/.claude/projects/` - The encoded path includes leading hyphen: `-Users-me-Projects-myapp` ### "Failed to parse session" - Session file may be corrupted - Check for valid JSON on each line - Malformed lines are skipped automatically ### "Insight extraction failed" - Verify Ollama is running: `ollama list` - Check model is available: `ollama pull llama3.1:8b` - Check logs for API errors --- ## API Reference ### REST Endpoints | Endpoint | Method | Description | |----------|--------|-------------| | `/api/sessions` | GET | List project sessions | | `/api/sessions/{id}` | GET | Get session details | | `/api/sessions/{id}/summary` | GET | Get session summary | ### MCP Tools | Tool | Description | |------|-------------| | `mcp__code-forge__list_sessions` | List sessions for a project | | `mcp__code-forge__get_session` | Get session details | | `mcp__code-forge__get_session_summary` | Get formatted summary | --- **See Also:** - [API Reference](../API_REFERENCE.md) - Session API endpoints - [Self Learning System](../SELF_LEARNING_SYSTEM.md) - How Claude learns - [README](../../README.md) - Full Claude OS documentation