#!/usr/bin/env bash # CLAUDE.md Guardian Check Script # 在 SessionStart 时运行,检查项目变化 set -euo pipefail # 获取脚本所在目录的父目录(项目根目录) SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" GUARDIAN_DIR="$PROJECT_ROOT/.claude/guardian" SNAPSHOT_FILE="$GUARDIAN_DIR/snapshot.json" LOG_FILE="$GUARDIAN_DIR/guardian.log" # 确保目录存在 mkdir -p "$GUARDIAN_DIR" log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" >> "$LOG_FILE" } # 计算目录结构哈希(使用绝对路径) get_structure_hash() { cd "$PROJECT_ROOT" find . -type f \( -name "*.md" -o -name "*.sh" -o -name "*.json" \) \ ! -path "./content-forge/*" \ ! -path "./.git/*" \ ! -path "./node_modules/*" \ ! -path "./.claude/guardian/*" \ -exec md5sum {} \; 2>/dev/null | sort | md5sum | cut -d' ' -f1 } # 获取 skills 列表 get_skills() { ls -1 "$PROJECT_ROOT/.claude/skills/" 2>/dev/null | sort | tr '\n' ',' | sed 's/,$//' } # 获取 commands 列表 get_commands() { ls -1 "$PROJECT_ROOT/.claude/commands/" 2>/dev/null | sed 's/.md$//' | sort | tr '\n' ',' | sed 's/,$//' } # 检查是否首次运行 if [[ ! -f "$SNAPSHOT_FILE" ]]; then log "首次运行,创建初始快照" HASH=$(get_structure_hash) SKILLS=$(get_skills) COMMANDS=$(get_commands) # 创建初始快照 cat > "$SNAPSHOT_FILE" << EOF { "last_check": "$(date -Iseconds)", "structure_hash": "$HASH", "skills": "$SKILLS", "commands": "$COMMANDS", "version": "1.0.0" } EOF echo "GUARDIAN: 初始化完成,快照已创建" exit 0 fi # 对比变化 CURRENT_HASH=$(get_structure_hash) STORED_HASH=$(jq -r '.structure_hash' "$SNAPSHOT_FILE") CURRENT_SKILLS=$(get_skills) STORED_SKILLS=$(jq -r '.skills' "$SNAPSHOT_FILE") CURRENT_COMMANDS=$(get_commands) STORED_COMMANDS=$(jq -r '.commands' "$SNAPSHOT_FILE") CHANGES="" if [[ "$CURRENT_HASH" != "$STORED_HASH" ]]; then CHANGES="${CHANGES}结构变化 detected\n" fi if [[ "$CURRENT_SKILLS" != "$STORED_SKILLS" ]]; then CHANGES="${CHANGES}Skills 变化: $STORED_SKILLS -> $CURRENT_SKILLS\n" fi if [[ "$CURRENT_COMMANDS" != "$STORED_COMMANDS" ]]; then CHANGES="${CHANGES}Commands 变化: $STORED_COMMANDS -> $CURRENT_COMMANDS\n" fi if [[ -n "$CHANGES" ]]; then log "检测到变化: $CHANGES" # 更新快照 cat > "$SNAPSHOT_FILE" << EOF { "last_check": "$(date -Iseconds)", "structure_hash": "$CURRENT_HASH", "skills": "$CURRENT_SKILLS", "commands": "$CURRENT_COMMANDS", "version": "1.0.0" } EOF echo "GUARDIAN: 检测到项目变化,建议更新 CLAUDE.md" echo "变化内容:" echo -e "$CHANGES" echo "" echo "运行 /claudeforge-skill 来更新 CLAUDE.md" else log "无变化" # 静默退出,不输出任何内容 fi