#!/bin/bash # Continuous Learning - Session Evaluator # Runs on Stop hook to extract reusable patterns from Claude Code sessions # # Why Stop hook instead of UserPromptSubmit: # - Stop runs once at session end (lightweight) # - UserPromptSubmit runs every message (heavy, adds latency) # # Hook config (in ~/.claude/settings.json): # { # "hooks": { # "Stop": [{ # "matcher": "*", # "hooks": [{ # "type": "command", # "command": "~/.claude/skills/continuous-learning/evaluate-session.sh" # }] # }] # } # } # # Patterns to detect: error_resolution, debugging_techniques, workarounds, project_specific # Patterns to ignore: simple_typos, one_time_fixes, external_api_issues # Extracted skills saved to: ~/.claude/skills/learned/ set -e SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" CONFIG_FILE="$SCRIPT_DIR/config.json" LEARNED_SKILLS_PATH="${HOME}/.claude/skills/learned" MIN_SESSION_LENGTH=10 # Load config if exists if [ -f "$CONFIG_FILE" ]; then MIN_SESSION_LENGTH=$(jq -r '.min_session_length // 10' "$CONFIG_FILE") LEARNED_SKILLS_PATH=$(jq -r '.learned_skills_path // "~/.claude/skills/learned/"' "$CONFIG_FILE" | sed "s|~|$HOME|") fi # Ensure learned skills directory exists mkdir -p "$LEARNED_SKILLS_PATH" # Get transcript path from environment (set by Claude Code) transcript_path="${CLAUDE_TRANSCRIPT_PATH:-}" if [ -z "$transcript_path" ] || [ ! -f "$transcript_path" ]; then exit 0 fi # Count messages in session message_count=$(grep -c '"type":"user"' "$transcript_path" 2>/dev/null || echo "0") # Skip short sessions if [ "$message_count" -lt "$MIN_SESSION_LENGTH" ]; then echo "[ContinuousLearning] Session too short ($message_count messages), skipping" >&2 exit 0 fi # Signal to Claude that session should be evaluated for extractable patterns echo "[ContinuousLearning] Session has $message_count messages - evaluate for extractable patterns" >&2 echo "[ContinuousLearning] Save learned skills to: $LEARNED_SKILLS_PATH" >&2