smart_context_loader.sh
1 #!/usr/bin/env bash 2 # Smart Context Loader for LocalCode 3 # Detects keywords in queries and loads relevant claude.md files 4 5 set -euo pipefail 6 7 PROJECT_ROOT="${PROJECT_ROOT:-$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)}" 8 9 # Color output 10 BLUE='\033[0;34m' 11 YELLOW='\033[1;33m' 12 NC='\033[0m' # No Color 13 14 info() { 15 echo -e "${BLUE}[Smart Context]${NC} $1" >&2 16 } 17 18 warn() { 19 echo -e "${YELLOW}[Smart Context]${NC} $1" >&2 20 } 21 22 # Keyword to claude.md mapping 23 # Format: "keyword1|keyword2:path/to/claude.md:priority" 24 declare -a KEYWORD_MAPS=( 25 # Agents & Development 26 "agent|agents|ceo|cto|chro:apps/claude.md:high" 27 "delegator|resource|optimization:apps/delegator/claude.md:high" 28 "shared|library|messageBus|decision:apps/echo_shared/claude.md:medium" 29 30 # Testing 31 "test|testing|integration|e2e|fixture:test/claude.md:high" 32 "benchmark|performance|llm|model:benchmark_models/claude.md:medium" 33 34 # Development Tools 35 "script|localcode|lc_query|lc_start:scripts/claude.md:medium" 36 "training|day2|day3:training/claude.md:low" 37 38 # Workflows & Monitoring 39 "workflow|orchestration|flow:workflows/claude.md:medium" 40 "monitor|dashboard|phoenix|liveview:monitor/claude.md:medium" 41 42 # Deployment 43 "docker|container|compose:docker/claude.md:medium" 44 "kubernetes|k8s|kubectl|helm:k8s/claude.md:medium" 45 46 # Troubleshooting 47 "database|postgres|psql|migration:docs/snippets/database_troubleshooting.md:high" 48 "ollama|model|inference|timeout:docs/snippets/ollama_troubleshooting.md:high" 49 "git|commit|pr|pull request:docs/snippets/git_workflow.md:low" 50 ) 51 52 # Detect keywords in query 53 detect_keywords() { 54 local query="$1" 55 local query_lower=$(echo "$query" | tr '[:upper:]' '[:lower:]') 56 57 declare -a detected_files=() 58 declare -a priorities=() 59 60 for mapping in "${KEYWORD_MAPS[@]}"; do 61 local keywords=$(echo "$mapping" | cut -d: -f1) 62 local file_path=$(echo "$mapping" | cut -d: -f2) 63 local priority=$(echo "$mapping" | cut -d: -f3) 64 65 # Check if any keyword matches 66 IFS='|' read -ra KW_ARRAY <<< "$keywords" 67 for keyword in "${KW_ARRAY[@]}"; do 68 if echo "$query_lower" | grep -qw "$keyword"; then 69 detected_files+=("$file_path") 70 priorities+=("$priority") 71 break # Only add file once per mapping 72 fi 73 done 74 done 75 76 # Remove duplicates while preserving order 77 declare -a unique_files=() 78 for file in "${detected_files[@]}"; do 79 if [[ ! " ${unique_files[@]} " =~ " ${file} " ]]; then 80 unique_files+=("$file") 81 fi 82 done 83 84 # Return detected files 85 printf '%s\n' "${unique_files[@]}" 86 } 87 88 # Load relevant claude.md content (condensed) 89 load_relevant_context() { 90 local file_path="$1" 91 local full_path="$PROJECT_ROOT/$file_path" 92 93 if [[ ! -f "$full_path" ]]; then 94 warn "File not found: $file_path" 95 return 96 fi 97 98 # Load first 50 lines (condensed context) or specific sections 99 local filename=$(basename "$file_path") 100 101 echo "# Context from $filename" 102 echo "" 103 104 case "$filename" in 105 "claude.md") 106 # Load Purpose + Quick Start (first 80 lines typically) 107 head -80 "$full_path" | grep -A 100 "## Purpose" | head -60 108 ;; 109 "database_troubleshooting.md"|"ollama_troubleshooting.md"|"testing_commands.md"|"git_workflow.md") 110 # Load full snippet (these are already condensed) 111 cat "$full_path" 112 ;; 113 *) 114 # Load first 50 lines as default 115 head -50 "$full_path" 116 ;; 117 esac 118 119 echo "" 120 echo "---" 121 echo "" 122 } 123 124 # Build smart context for query 125 build_smart_context() { 126 local query="$1" 127 local max_files="${2:-3}" # Limit to avoid context overflow 128 129 info "Analyzing query for relevant context..." 130 131 local detected_files=$(detect_keywords "$query") 132 133 if [[ -z "$detected_files" ]]; then 134 warn "No specific keywords detected. Using base context." 135 return 0 136 fi 137 138 local file_count=0 139 echo "$detected_files" | while read -r file_path; do 140 if [[ $file_count -ge $max_files ]]; then 141 warn "Reached max context files limit ($max_files). Skipping remaining." 142 break 143 fi 144 145 info "Loading context from: $file_path" 146 load_relevant_context "$file_path" 147 148 ((file_count++)) 149 done 150 } 151 152 # Main entry point 153 main() { 154 local query="${1:-}" 155 local max_files="${2:-3}" 156 157 if [[ -z "$query" ]]; then 158 echo "Usage: $0 <query> [max_files]" 159 echo "" 160 echo "Detects keywords and loads relevant claude.md context." 161 echo "" 162 echo "Examples:" 163 echo " $0 'How do agents communicate?' # Loads apps/claude.md" 164 echo " $0 'Fix database connection' # Loads docs/snippets/database_troubleshooting.md" 165 echo " $0 'Deploy to Kubernetes' # Loads k8s/claude.md" 166 exit 1 167 fi 168 169 build_smart_context "$query" "$max_files" 170 } 171 172 # Run if executed directly 173 if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then 174 main "$@" 175 fi