#!/bin/bash # Validate the Claude Code configuration setup # Run this after changes to ensure everything is properly configured set -euo pipefail CLAUDE_DIR="${HOME}/.claude" ERRORS=0 WARNINGS=0 # Colors RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' # No Color pass() { echo -e "${GREEN}✓${NC} $1"; } fail() { echo -e "${RED}✗${NC} $1"; ((ERRORS++)); } warn() { echo -e "${YELLOW}!${NC} $1"; ((WARNINGS++)); } echo "Validating Claude Code configuration..." echo "" # Check required directories echo "=== Directory Structure ===" for dir in agents commands hooks mcp skills state workflows automation; do if [[ -d "${CLAUDE_DIR}/${dir}" ]]; then pass "${dir}/ exists" else fail "${dir}/ missing" fi done echo "" # Check required files echo "=== Core Files ===" for file in CLAUDE.md README.md settings.json .gitignore; do if [[ -f "${CLAUDE_DIR}/${file}" ]]; then pass "${file} exists" else fail "${file} missing" fi done echo "" # Check plugin manifest echo "=== Plugin Structure ===" if [[ -f "${CLAUDE_DIR}/.claude-plugin/plugin.json" ]]; then pass "plugin.json exists" if python3 -c "import json; json.load(open('${CLAUDE_DIR}/.claude-plugin/plugin.json'))" 2>/dev/null; then pass "plugin.json is valid JSON" else fail "plugin.json is invalid JSON" fi else warn "plugin.json missing (optional for local use)" fi echo "" # Check hooks echo "=== Hooks ===" if [[ -f "${CLAUDE_DIR}/hooks/hooks.json" ]]; then pass "hooks.json exists" if python3 -c "import json; json.load(open('${CLAUDE_DIR}/hooks/hooks.json'))" 2>/dev/null; then pass "hooks.json is valid JSON" else fail "hooks.json is invalid JSON" fi else warn "hooks.json missing" fi for script in session-start.sh pre-compact.sh; do if [[ -x "${CLAUDE_DIR}/hooks/scripts/${script}" ]]; then pass "hooks/scripts/${script} is executable" elif [[ -f "${CLAUDE_DIR}/hooks/scripts/${script}" ]]; then fail "hooks/scripts/${script} exists but not executable" fi done echo "" # Check skills echo "=== Skills ===" for skill in gmail gcal k8s-quick-status sysadmin-health usage programmer-add-project; do skill_dir="${CLAUDE_DIR}/skills/${skill}" if [[ -f "${skill_dir}/SKILL.md" ]]; then pass "${skill}/SKILL.md exists" # Check for scripts directory if [[ -d "${skill_dir}/scripts" ]]; then script_count=$(find "${skill_dir}/scripts" -type f \( -name "*.py" -o -name "*.sh" \) | wc -l) if [[ ${script_count} -gt 0 ]]; then pass "${skill}/scripts/ has ${script_count} script(s)" # Check executability while IFS= read -r script; do [[ -f "$script" ]] || continue if [[ -x "$script" ]]; then pass "$(basename "$script") is executable" else fail "$(basename "$script") not executable" fi done < <(find "${skill_dir}/scripts" -type f \( -name "*.py" -o -name "*.sh" \) 2>/dev/null) fi fi else fail "${skill}/SKILL.md missing" fi done echo "" # Check state files echo "=== State Files ===" for file in component-registry.json autonomy-levels.json model-policy.json; do state_file="${CLAUDE_DIR}/state/${file}" if [[ -f "${state_file}" ]]; then pass "state/${file} exists" if python3 -c "import json; json.load(open('${state_file}'))" 2>/dev/null; then pass "state/${file} is valid JSON" else fail "state/${file} is invalid JSON" fi else fail "state/${file} missing" fi done echo "" # Check Gmail setup echo "=== Gmail Integration ===" if [[ -d "${CLAUDE_DIR}/mcp/gmail/venv" ]]; then pass "Gmail venv exists" if [[ -f "${CLAUDE_DIR}/mcp/gmail/venv/bin/python" ]]; then pass "Gmail venv has Python" else fail "Gmail venv missing Python" fi else warn "Gmail venv not set up" fi if [[ -f "${HOME}/.gmail-mcp/credentials.json" ]]; then pass "Gmail credentials exist" else warn "Gmail credentials missing (~/.gmail-mcp/credentials.json)" fi echo "" # Check READMEs echo "=== Documentation ===" readme_count=0 for dir in agents commands hooks mcp skills state workflows; do if [[ -f "${CLAUDE_DIR}/${dir}/README.md" ]]; then readme_count=$((readme_count + 1)) else warn "${dir}/README.md missing" fi done pass "${readme_count}/7 directory READMEs present" echo "" # Summary echo "=== Summary ===" if [[ ${ERRORS} -eq 0 && ${WARNINGS} -eq 0 ]]; then echo -e "${GREEN}All checks passed!${NC}" elif [[ ${ERRORS} -eq 0 ]]; then echo -e "${YELLOW}${WARNINGS} warning(s), 0 errors${NC}" else echo -e "${RED}${ERRORS} error(s), ${WARNINGS} warning(s)${NC}" fi exit ${ERRORS}