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 accomplish debug • implement • refactor • test • explore • document
Problem Domain Technical areas you’re working in Extracted from file paths and tool inputs
Workflow Type Problem-solving approach used TDD • Debug-Systematic • Refactor-Safe • Explore-Then-Implement
Success Indicators Session effectiveness metrics Tool 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 calls successfulTools / totalTools
Total Tools Used Number of tool invocations Count of all tool calls
Session Duration Time from first to last tool In 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
Analyze a complete session with full context Parameters:
sessionId: string — Session identifier
events: ToolEvent[] — Tool events for this session
conversationLog?: string — Optional full conversation transcript
Returns: SessionContext
detectProblemSolvingPatterns
Detect high-level problem-solving patterns across sessions Parameters:
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