#!/bin/bash # Debug script for troubleshooting Claude Code configuration # Usage: ./debug.sh [--full|--json|--paths] set -euo pipefail CLAUDE_DIR="${HOME}/.claude" # Colors RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' info() { echo -e "${BLUE}ℹ${NC} $1"; } ok() { echo -e "${GREEN}✓${NC} $1"; } warn() { echo -e "${YELLOW}⚠${NC} $1"; } error() { echo -e "${RED}✗${NC} $1"; } show_paths() { echo "" echo "=== Configuration Paths ===" echo "" echo "CLAUDE_DIR: ${CLAUDE_DIR}" echo "" echo "Key files:" echo " CLAUDE.md: ${CLAUDE_DIR}/CLAUDE.md" echo " plugin.json: ${CLAUDE_DIR}/.claude-plugin/plugin.json" echo " hooks.json: ${CLAUDE_DIR}/hooks/hooks.json" echo " registry.json: ${CLAUDE_DIR}/state/component-registry.json" echo "" echo "Memory:" echo " preferences: ${CLAUDE_DIR}/state/personal-assistant/memory/preferences.json" echo " decisions: ${CLAUDE_DIR}/state/personal-assistant/memory/decisions.json" echo " history index: ${CLAUDE_DIR}/state/personal-assistant/history/index.json" echo "" echo "Logs:" echo " maintenance: ${CLAUDE_DIR}/logs/maintenance-*.log" echo "" } check_file() { local path="$1" local name="$2" if [[ -f "$path" ]]; then local size=$(stat -c %s "$path" 2>/dev/null || stat -f %z "$path" 2>/dev/null || echo "?") ok "$name ($size bytes)" return 0 else error "$name (missing)" return 1 fi } check_json() { local path="$1" local name="$2" if [[ -f "$path" ]]; then if python3 -c "import json; json.load(open('$path'))" 2>/dev/null; then ok "$name (valid JSON)" return 0 else error "$name (invalid JSON)" return 1 fi else warn "$name (file missing)" return 1 fi } check_script() { local path="$1" local name="$2" if [[ -f "$path" ]]; then if [[ -x "$path" ]]; then ok "$name (executable)" else warn "$name (not executable)" fi else error "$name (missing)" fi } show_summary() { echo "" echo "🔍 Claude Code Debug Report" echo " Generated: $(date)" echo "" # Version echo "=== Version ===" if [[ -f "${CLAUDE_DIR}/VERSION" ]]; then echo " Version: $(cat "${CLAUDE_DIR}/VERSION")" else echo " Version: unknown" fi echo "" # Core files echo "=== Core Files ===" check_file "${CLAUDE_DIR}/CLAUDE.md" "CLAUDE.md" check_json "${CLAUDE_DIR}/.claude-plugin/plugin.json" "plugin.json" check_json "${CLAUDE_DIR}/hooks/hooks.json" "hooks.json" check_json "${CLAUDE_DIR}/state/component-registry.json" "component-registry.json" echo "" # State files echo "=== State Files ===" check_json "${CLAUDE_DIR}/state/personal-assistant-preferences.json" "PA preferences" check_json "${CLAUDE_DIR}/state/personal-assistant/session-context.json" "Session context" check_json "${CLAUDE_DIR}/state/personal-assistant/general-instructions.json" "General instructions" check_json "${CLAUDE_DIR}/state/sysadmin/session-autonomy.json" "Sysadmin autonomy" echo "" # Memory echo "=== Memory Files ===" check_json "${CLAUDE_DIR}/state/personal-assistant/memory/preferences.json" "Memory: preferences" check_json "${CLAUDE_DIR}/state/personal-assistant/memory/decisions.json" "Memory: decisions" check_json "${CLAUDE_DIR}/state/personal-assistant/memory/projects.json" "Memory: projects" check_json "${CLAUDE_DIR}/state/personal-assistant/memory/facts.json" "Memory: facts" check_json "${CLAUDE_DIR}/state/personal-assistant/history/index.json" "History index" echo "" # Scripts echo "=== Key Scripts ===" check_script "${CLAUDE_DIR}/automation/validate-setup.sh" "validate-setup.sh" check_script "${CLAUDE_DIR}/automation/quick-status.sh" "quick-status.sh" check_script "${CLAUDE_DIR}/automation/backup.sh" "backup.sh" check_script "${CLAUDE_DIR}/automation/install.sh" "install.sh" check_script "${CLAUDE_DIR}/hooks/scripts/session-start.sh" "session-start.sh" echo "" # Skills echo "=== Skills ===" skill_count=$(find "${CLAUDE_DIR}/skills" -name "SKILL.md" 2>/dev/null | wc -l) echo " Skills found: $skill_count" find "${CLAUDE_DIR}/skills" -name "SKILL.md" -exec dirname {} \; 2>/dev/null | while read dir; do echo " - $(basename "$dir")" done echo "" # Commands echo "=== Commands ===" cmd_count=$(find "${CLAUDE_DIR}/commands" -name "*.md" ! -name "README.md" 2>/dev/null | wc -l) echo " Commands found: $cmd_count" echo "" # Agents echo "=== Agents ===" agent_count=$(find "${CLAUDE_DIR}/agents" -name "*.md" ! -name "README.md" 2>/dev/null | wc -l) echo " Agent files found: $agent_count" echo "" # Environment echo "=== Environment ===" echo " HOME: $HOME" echo " USER: ${USER:-$(whoami)}" echo " Shell: ${SHELL:-unknown}" echo " Python: $(python3 --version 2>&1 || echo 'not found')" if command -v kubectl &> /dev/null; then ok "kubectl installed" else warn "kubectl not found" fi echo "" # Disk usage echo "=== Disk Usage ===" total=$(du -sh "${CLAUDE_DIR}" 2>/dev/null | cut -f1) echo " Total: $total" echo "" echo " By directory:" du -sh "${CLAUDE_DIR}"/{agents,automation,commands,hooks,mcp,skills,state,workflows,logs,backups} 2>/dev/null | while read size dir; do echo " $(basename "$dir"): $size" done echo "" } show_json() { echo "{" echo " \"version\": \"$(cat "${CLAUDE_DIR}/VERSION" 2>/dev/null || echo 'unknown')\"," echo " \"timestamp\": \"$(date -Iseconds)\"," echo " \"paths\": {" echo " \"claude_dir\": \"${CLAUDE_DIR}\"," echo " \"home\": \"$HOME\"" echo " }," # Count components skill_count=$(find "${CLAUDE_DIR}/skills" -name "SKILL.md" 2>/dev/null | wc -l | tr -d ' ') cmd_count=$(find "${CLAUDE_DIR}/commands" -name "*.md" ! -name "README.md" 2>/dev/null | wc -l | tr -d ' ') agent_count=$(find "${CLAUDE_DIR}/agents" -name "*.md" ! -name "README.md" 2>/dev/null | wc -l | tr -d ' ') echo " \"components\": {" echo " \"skills\": $skill_count," echo " \"commands\": $cmd_count," echo " \"agents\": $agent_count" echo " }," # Check files files_ok=true for f in CLAUDE.md .claude-plugin/plugin.json hooks/hooks.json state/component-registry.json; do if [[ ! -f "${CLAUDE_DIR}/$f" ]]; then files_ok=false break fi done echo " \"status\": {" echo " \"core_files\": $files_ok," echo " \"python\": $(python3 --version &>/dev/null && echo true || echo false)," echo " \"kubectl\": $(command -v kubectl &>/dev/null && echo true || echo false)" echo " }" echo "}" } # Parse arguments case "${1:-}" in --paths) show_paths ;; --json) show_json ;; --full|*) show_summary ;; esac