Skip to main content

Session Analysis

The Session Analyzer goes beyond simple tool patterns to understand full conversation context, decision-making patterns, and problem-solving strategies from your coding agent sessions.

What Gets Analyzed

User Intent

What you’re trying to accomplishdebug • implement • refactor • test • explore • document

Problem Domain

Technical areas you’re working inExtracted from file paths and tool inputs

Workflow Type

Problem-solving approach usedTDD • Debug-Systematic • Refactor-Safe • Explore-Then-Implement

Success Indicators

Session effectiveness metricsTool success rate • Duration • Outcome

SessionContext Type

The complete analysis result:
// From types/index.ts:80-92
export interface SessionContext {
  sessionId: string;
  startTime: string;               // ISO-8601
  endTime: string;
  projectPath: string;
  turns: ConversationTurn[];       // Parsed conversation turns
  primaryIntent?: string | null;   // debug, implement, refactor, etc.
  problemDomains: string[];        // Extracted technical domains
  workflowType?: string | null;    // Detected workflow pattern
  successIndicators: Record<string, unknown>;
  keyDecisions: string[];          // Future: track decision points
}

ConversationTurn Type

Individual turns in the session:
// From types/index.ts:68-78
export interface ConversationTurn {
  sessionId: string;
  timestamp: string;
  userMessage: string | null;
  claudeResponse: string | null;
  toolsUsed: string[];             // Tools used in this turn
  intentCategory?: string | null;  // Categorized intent
  problemDomain?: string | null;   // Domain for this turn
  outcome?: string | null;         // Success/failure/partial
}

Intent Detection

User intent is detected by keyword scoring across conversation turns:
// From session-analyzer.ts:20-28
const INTENT_KEYWORDS: Record<string, string[]> = {
  debug: ["bug", "error", "fix", "issue", "problem", "not working", "broken"],
  implement: ["create", "add", "implement", "build", "make", "new feature"],
  refactor: ["refactor", "clean up", "reorganize", "improve", "optimize"],
  test: ["test", "TDD", "unit test", "testing", "coverage"],
  explore: ["understand", "explain", "how does", "what is", "show me"],
  document: ["document", "comment", "README", "docs", "documentation"],
};
// From session-analyzer.ts:174-205
function detectPrimaryIntent(turns: ConversationTurn[]): string | null {
  const intentScores: Record<string, number> = {};
  
  // Initialize scores
  for (const intent of Object.keys(INTENT_KEYWORDS)) {
    intentScores[intent] = 0;
  }
  
  // Score each turn
  for (const turn of turns) {
    if (turn.userMessage) {
      const messageLower = turn.userMessage.toLowerCase();
      for (const [intent, keywords] of Object.entries(INTENT_KEYWORDS)) {
        for (const keyword of keywords) {
          if (messageLower.includes(keyword)) {
            intentScores[intent]++;  // +1 for each keyword match
          }
        }
      }
    }
  }
  
  // Return highest scoring intent
  const maxScore = Math.max(...Object.values(intentScores));
  if (maxScore > 0) {
    for (const [intent, score] of Object.entries(intentScores)) {
      if (score === maxScore) return intent;
    }
  }
  
  return null;
}

Workflow Type Detection

Workflow patterns are detected by matching tool sequences against known patterns:
// From session-analyzer.ts:30-51
const WORKFLOW_PATTERNS: Record<string, { toolSequence: string[], keywords: string[] }> = {
  TDD: {
    toolSequence: ["Write", "Bash", "Edit", "Bash"],
    keywords: ["test", "TDD", "red-green-refactor"],
  },
  "Debug-Systematic": {
    toolSequence: ["Read", "Grep", "Bash", "Edit"],
    keywords: ["error", "bug", "debug", "fix"],
  },
  "Refactor-Safe": {
    toolSequence: ["Read", "Edit", "Bash"],
    keywords: ["refactor", "improve", "clean"],
  },
  "Explore-Then-Implement": {
    toolSequence: ["Grep", "Read", "Write"],
    keywords: ["understand", "then", "create"],
  },
};
Workflow detection uses subsequence matching — the tool sequence just needs to contain the pattern, not be an exact match.
// From session-analyzer.ts:237-250
function detectWorkflowType(
  events: ToolEvent[],
  turns: ConversationTurn[]
): string | null {
  const toolSequence = events.map((e) => e.toolName);
  
  for (const [workflowType, patternInfo] of Object.entries(WORKFLOW_PATTERNS)) {
    if (containsSubsequence(toolSequence, patternInfo.toolSequence)) {
      return workflowType;
    }
  }
  
  return null;
}

Problem Domain Extraction

Technical domains are extracted from file paths in tool inputs:
// From session-analyzer.ts:207-232
function extractProblemDomains(
  turns: ConversationTurn[],
  events: ToolEvent[]
): string[] {
  const domains = new Set<string>();
  
  for (const event of events) {
    const pathValue =
      (event.toolInput?.path as string) ??
      (event.toolInput?.file_path as string) ??
      null;
    
    if (pathValue) {
      // Extract parent directory as domain
      const parts = pathValue.replace(/\\/g, "/").split("/").filter(Boolean);
      if (parts.length > 1) {
        domains.add(parts[parts.length - 2]);  // Parent directory name
      }
    }
  }
  
  return [...domains].sort().slice(0, 5);  // Top 5 domains
}
Example: If you edit src/api/handlers.ts, src/database/repo.ts, and src/api/routes.ts, the detected domains would be ["api", "database"].

Turn Parsing

Conversation turns are parsed by grouping events with 60-second gaps:
// From session-analyzer.ts:117-169
function parseConversationTurns(
  sessionId: string,
  events: ToolEvent[]
): ConversationTurn[] {
  const turns: ConversationTurn[] = [];
  let currentTurnTools: string[] = [];
  let currentTimestamp: string | null = null;
  
  for (const event of events) {
    if (currentTimestamp !== null) {
      const gap = parseTimestamp(event.timestamp) - parseTimestamp(currentTimestamp);
      
      if (gap > 60_000) {  // 1 minute gap = new turn
        if (currentTurnTools.length > 0) {
          turns.push({
            sessionId,
            timestamp: currentTimestamp,
            userMessage: null,
            claudeResponse: null,
            toolsUsed: currentTurnTools,
            intentCategory: null,
            problemDomain: null,
            outcome: null,
          });
        }
        currentTurnTools = [];
      }
    }
    
    currentTurnTools.push(event.toolName);
    currentTimestamp = event.timestamp;
  }
  
  // Don't forget the last turn
  if (currentTurnTools.length > 0 && currentTimestamp !== null) {
    turns.push({ /* ... */ });
  }
  
  return turns;
}

Success Indicators

Session effectiveness is measured by multiple indicators:
// From session-analyzer.ts:252-273
function calculateSuccessIndicators(
  events: ToolEvent[]
): Record<string, unknown> {
  const totalTools = events.length;
  const successfulTools = events.filter((e) => e.success).length;
  
  let durationMinutes = 0;
  if (events.length >= 2) {
    const startMs = parseTimestamp(events[0].timestamp);
    const endMs = parseTimestamp(events[events.length - 1].timestamp);
    durationMinutes = (endMs - startMs) / 60_000;
  }
  
  return {
    tool_success_rate: totalTools > 0 ? successfulTools / totalTools : 0,
    total_tools_used: totalTools,
    session_duration_minutes: durationMinutes,
  };
}

Tool Success Rate

Percentage of successful tool callssuccessfulTools / totalTools

Total Tools Used

Number of tool invocationsCount of all tool calls

Session Duration

Time from first to last toolIn minutes

Problem-Solving Patterns

The analyzer can detect high-level problem-solving patterns across multiple sessions:
// From session-analyzer.ts:331-420
function detectProblemSolvingPatterns(
  sessions: Array<{ sessionId: string; events: ToolEvent[] }>
): ProblemSolvingPattern[] {
  // 1. Analyze each session
  const sessionContexts = sessions.map((s) =>
    analyzeSession(s.sessionId, s.events)
  );
  
  // 2. Group by workflow type
  const workflowGroups = new Map<string, SessionContext[]>();
  for (const ctx of sessionContexts) {
    if (ctx.workflowType) {
      const existing = workflowGroups.get(ctx.workflowType);
      if (existing) {
        existing.push(ctx);
      } else {
        workflowGroups.set(ctx.workflowType, [ctx]);
      }
    }
  }
  
  // 3. Create patterns from groups (minimum 2 occurrences)
  const patterns: ProblemSolvingPattern[] = [];
  for (const [workflowType, contexts] of workflowGroups) {
    if (contexts.length < 2) continue;
    
    // Calculate success rate
    const successCount = contexts.filter(
      (ctx) => (ctx.successIndicators as Record<string, number>).tool_success_rate > 0.8
    ).length;
    const successRate = successCount / contexts.length;
    
    // Get common domains and intents
    // ...
    
    patterns.push({
      patternId: `ps-${workflowType}`,
      patternType: workflowType,
      description: `Problem-solving pattern: ${workflowType}`,
      workflowSteps: ["Analyze problem", "Plan approach", "Implement solution", "Verify"],
      successRate,
      occurrenceCount: contexts.length,
      exampleSessions: contexts.slice(0, 3).map((ctx) => ctx.sessionId),
      contextualIndicators: {
        primary_intents: primaryIntents,
        common_domains: topDomains,
      },
    });
  }
  
  // Sort by success rate descending
  patterns.sort((a, b) => b.successRate - a.successRate);
  return patterns;
}

ProblemSolvingPattern Type

// From types/index.ts:94-104
export interface ProblemSolvingPattern {
  patternId: string;
  patternType: string;              // TDD, Debug-Systematic, etc.
  description: string;
  workflowSteps: string[];          // High-level procedural steps
  successRate: number;              // 0.0 - 1.0
  occurrenceCount: number;
  exampleSessions: string[];
  contextualIndicators: Record<string, unknown>;  // Intents, domains
}

Usage Example

Analyze a Single Session

import { createSessionAnalyzer } from "./core/session-analyzer";
import { createEventStore } from "./core/event-store";

const eventStore = createEventStore();
const analyzer = createSessionAnalyzer();

// Get events for a session
const sessionId = "session-abc123";
const events = eventStore.getSessionEvents(sessionId);

// Analyze the session
const context = analyzer.analyzeSession(sessionId, events);

console.log(`Primary intent: ${context.primaryIntent}`);
console.log(`Workflow type: ${context.workflowType}`);
console.log(`Problem domains: ${context.problemDomains.join(", ")}`);
console.log(`Success rate: ${context.successIndicators.tool_success_rate}`);
console.log(`Duration: ${context.successIndicators.session_duration_minutes} min`);

Detect Problem-Solving Patterns

import { createSessionAnalyzer } from "./core/session-analyzer";
import { createEventStore } from "./core/event-store";

const eventStore = createEventStore();
const analyzer = createSessionAnalyzer();

// Get all recent sessions
const eventSessions = eventStore.getEventsWithInputs(undefined, 30);  // Last 30 days
const sessions = eventSessions.map((events, idx) => ({
  sessionId: events[0]?.sessionId ?? `session-${idx}`,
  events
}));

// Detect patterns
const patterns = analyzer.detectProblemSolvingPatterns(sessions);

for (const pattern of patterns) {
  console.log(`\n${pattern.patternType}:`);
  console.log(`  Success rate: ${Math.round(pattern.successRate * 100)}%`);
  console.log(`  Used ${pattern.occurrenceCount} times`);
  console.log(`  Steps: ${pattern.workflowSteps.join(" → ")}`);
}
Output:
TDD:
  Success rate: 92%
  Used 8 times
  Steps: Analyze problem → Plan approach → Implement solution → Verify

Debug-Systematic:
  Success rate: 85%
  Used 12 times
  Steps: Analyze problem → Plan approach → Implement solution → Verify

Integration with Pattern Detection

Session analysis enriches detected patterns with contextual understanding:
// From pattern-detector.ts:288-350
function enhanceWithV2(
  pattern: DetectedPattern,
  eventSessions: ToolEvent[][],
  sessionIndices: number[]
): void {
  // Session context analysis: analyze up to 5 sessions
  const contextsToAnalyze = sessionIndices.slice(0, 5);
  const sessionContexts = contextsToAnalyze
    .filter((idx) => idx < eventSessions.length && eventSessions[idx].length > 0)
    .map((idx) => {
      const events = eventSessions[idx];
      return sessionAnalyzer.analyzeSession(events[0].sessionId, events);
    });
  
  if (sessionContexts.length > 0) {
    // Aggregate session insights
    const primaryIntents = sessionContexts
      .map((ctx) => ctx.primaryIntent)
      .filter((i): i is string => i !== null && i !== undefined);
    
    const avgToolSuccess =
      sessionContexts.reduce(
        (sum, ctx) => sum + (ctx.successIndicators.tool_success_rate ?? 0),
        0
      ) / sessionContexts.length;
    
    pattern.sessionContext = {
      primaryIntent: getMostFrequent(primaryIntents),
      problemDomains: [...new Set(allDomains)].slice(0, 5),
      workflowType: getMostFrequent(workflowTypes),
      toolSuccessRate: Math.round(avgToolSuccess * 100) / 100,
      avgSessionDurationMinutes: Math.round(avgDuration * 10) / 10,
    };
  }
}

Session Context in Skills

Session analysis enriches generated skills with contextual information:
---
name: debug-systematic-workflow
session-analysis:
  primary_intent: debug
  problem_domains:
    - api
    - database
  workflow_type: Debug-Systematic
  tool_success_rate: 0.87
  avg_session_duration_minutes: 15.3
---

# debug-systematic-workflow

## Context

This workflow is most appropriate when:

- You are tracking down and fixing bugs
- Working in these areas: api, database
- Following a Debug-Systematic approach

Success rate in previous usage: 87%

API Reference

analyzeSession
function
Analyze a complete session with full contextParameters:
  • sessionId: string — Session identifier
  • events: ToolEvent[] — Tool events for this session
  • conversationLog?: string — Optional full conversation transcript
Returns: SessionContext
detectProblemSolvingPatterns
function
Detect high-level problem-solving patterns across sessionsParameters:
  • sessions: Array<{ sessionId: string; events: ToolEvent[] }> — Session data
Returns: ProblemSolvingPattern[] — Sorted by success rate descending

Next Steps

Pattern Detection

See how session context enhances pattern detection

Design Patterns

Explore workflow pattern recognition

Event Store

Learn about tool event capture and storage

Skill Generation

See how context enriches generated skills

Build docs developers (and LLMs) love