#!/usr/bin/env bash # Changelog sync guard:比较 Godot 源码/配置与本会话起点、changelog 的 mtime。 emit_empty() { printf '{}\n' } cat >/dev/null if [ -n "${CURSOR_SKIP_CHANGELOG:-}" ]; then emit_empty exit 0 fi script_dir=$(CDPATH= cd -- "$(dirname -- "${BASH_SOURCE[0]}")" 2>/dev/null && pwd) cursor_dir=$(dirname -- "$script_dir") repo_root=$(dirname -- "$cursor_dir") changelog="$cursor_dir/changelog/changelog-headlines.md" ack_file="$cursor_dir/changelog/.changelog-ack" session_marker="$cursor_dir/changelog/.session-start" if [ ! -f "$changelog" ]; then emit_empty exit 0 fi get_mtime() { stat -c %Y "$1" 2>/dev/null || stat -f %m "$1" 2>/dev/null } if [ -f "$ack_file" ]; then changelog_mtime=$(get_mtime "$changelog") ack_mtime=$(get_mtime "$ack_file") if [ -n "$changelog_mtime" ] && [ -n "$ack_mtime" ] && [ "$ack_mtime" -ge "$changelog_mtime" ] 2>/dev/null; then emit_empty exit 0 fi fi comparison_file=$changelog if [ -f "$session_marker" ]; then changelog_mtime=$(get_mtime "$changelog") session_mtime=$(get_mtime "$session_marker") if [ -n "$changelog_mtime" ] && [ -n "$session_mtime" ] && [ "$session_mtime" -gt "$changelog_mtime" ] 2>/dev/null; then comparison_file=$session_marker fi fi newer_file='' while IFS= read -r candidate; do newer_file=$candidate break done < <( find "$repo_root" \ \( -type d \( \ -name '.git' -o \ -name '.cursor' -o \ -name '.godot' -o \ -name 'node_modules' -o \ -name '__pycache__' -o \ -name 'venv' -o \ -name '.venv' -o \ -name 'dist' -o \ -name 'build' -o \ -name 'out' -o \ -name 'bin' -o \ -name 'obj' -o \ -name 'export' -o \ -name 'exports' -o \ -name 'coverage' -o \ -name 'tmp' -o \ -name 'temp' \ \) -prune \) -o \ \( -type f \( \ -iname 'project.godot' -o \ -iname '*.gd' -o \ -iname '*.tscn' -o \ -iname '*.tres' -o \ -iname '*.res' -o \ -iname '*.gdshader' -o \ -iname '*.cfg' -o \ -iname '*.json' -o \ -iname '*.cs' -o \ -iname '*.csproj' -o \ -iname '*.py' -o \ -iname '*.ps1' -o \ -iname '*.sh' \ \) -newer "$comparison_file" -print \) 2>/dev/null ) if [ -z "$newer_file" ]; then emit_empty exit 0 fi relative_file=${newer_file#"$repo_root"/} message="[Hook] Godot source/config is newer than the changelog (e.g. $relative_file). Run dev-changelog Skill operation A now: add a fragment under .cursor/changelog/entries/ and rebuild the changelog views." python_cmd='' for candidate in python3 python; do if command -v "$candidate" >/dev/null 2>&1 && "$candidate" -c 'import json' >/dev/null 2>&1; then python_cmd=$candidate break fi done if [ -n "$python_cmd" ]; then result=$( printf '%s' "$message" | "$python_cmd" -c ' import json import sys print(json.dumps( {"followup_message": sys.stdin.read()}, ensure_ascii=False, separators=(",", ":"), )) ' 2>/dev/null ) || result='{}' if [ -n "$result" ]; then printf '%s\n' "$result" else emit_empty fi else emit_empty fi exit 0