#!/bin/bash
set +e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
if [ -f "$SCRIPT_DIR/path-utils.sh" ]; then
source "$SCRIPT_DIR/path-utils.sh"
else
normalize_path() {
local p="$1"
p="${p//\\//}"
echo "$p"
}
is_path_under() {
local child="$1"
local parent="$2"
child="$(normalize_path "$child")"
parent="$(normalize_path "$parent")"
[[ "$parent" != */ ]] && parent="${parent}/"
[[ "${child}/" == "${parent}"* ]] || [ "$child" = "${parent%/}" ]
}
fi
INPUT=""
if [ ! -t 0 ]; then
INPUT="$(cat 2>/dev/null)"
fi
TOOL_NAME="${1:-}"
FILE_PATH="${2:-}"
CWD=""
if [ -n "$INPUT" ]; then
if command -v jq >/dev/null 2>&1; then
TOOL_NAME_FROM_STDIN="$(printf '%s' "$INPUT" | jq -r '.tool_name // empty' 2>/dev/null)"
FILE_PATH_FROM_STDIN="$(printf '%s' "$INPUT" | jq -r '.tool_input.file_path // .tool_response.filePath // empty' 2>/dev/null)"
CWD_FROM_STDIN="$(printf '%s' "$INPUT" | jq -r '.cwd // empty' 2>/dev/null)"
elif command -v python3 >/dev/null 2>&1; then
eval "$(printf '%s' "$INPUT" | python3 -c '
import json, shlex, sys
try:
data = json.load(sys.stdin)
except Exception:
data = {}
tool_name = data.get("tool_name") or ""
cwd = data.get("cwd") or ""
tool_input = data.get("tool_input") or {}
tool_response = data.get("tool_response") or {}
file_path = tool_input.get("file_path") or tool_response.get("filePath") or ""
print(f"TOOL_NAME_FROM_STDIN={shlex.quote(tool_name)}")
print(f"CWD_FROM_STDIN={shlex.quote(cwd)}")
print(f"FILE_PATH_FROM_STDIN={shlex.quote(file_path)}")
' 2>/dev/null)"
fi
[ -z "$TOOL_NAME" ] && TOOL_NAME="${TOOL_NAME_FROM_STDIN:-}"
[ -z "$FILE_PATH" ] && FILE_PATH="${FILE_PATH_FROM_STDIN:-}"
CWD="${CWD_FROM_STDIN:-}"
fi
TOOL_NAME="${TOOL_NAME:-unknown}"
if [ -n "$CWD" ] && [ -n "$FILE_PATH" ]; then
NORM_FILE_PATH="$(normalize_path "$FILE_PATH")"
NORM_CWD="$(normalize_path "$CWD")"
if is_path_under "$NORM_FILE_PATH" "$NORM_CWD"; then
cwd_with_slash="${NORM_CWD%/}/"
if [[ "$NORM_FILE_PATH" == "$cwd_with_slash"* ]]; then
FILE_PATH="${NORM_FILE_PATH#$cwd_with_slash}"
fi
fi
fi
STATE_FILE=".claude/state/session.json"
CURRENT_TIME=$(date -u +%Y-%m-%dT%H:%M:%SZ)
if [ ! -f "$STATE_FILE" ]; then
exit 0
fi
if [ -z "$FILE_PATH" ]; then
exit 0
fi
IMPORTANT_FILES="Plans.md CLAUDE.md AGENTS.md"
IS_IMPORTANT="false"
for important in $IMPORTANT_FILES; do
if [[ "$FILE_PATH" == *"$important"* ]]; then
IS_IMPORTANT="true"
break
fi
done
if [[ "$FILE_PATH" == *".test."* ]] || [[ "$FILE_PATH" == *".spec."* ]] || [[ "$FILE_PATH" == *"__tests__"* ]]; then
IS_IMPORTANT="true"
fi
if command -v jq &> /dev/null; then
TEMP_FILE=$(mktemp 2>/dev/null) || {
exit 0
}
trap 'rm -f "$TEMP_FILE"' EXIT
if jq --arg file "$FILE_PATH" \
--arg action "$TOOL_NAME" \
--arg timestamp "$CURRENT_TIME" \
--arg important "$IS_IMPORTANT" \
'.changes_this_session += [{
"file": $file,
"action": $action,
"timestamp": $timestamp,
"important": ($important == "true")
}]' "$STATE_FILE" > "$TEMP_FILE" 2>/dev/null; then
mv "$TEMP_FILE" "$STATE_FILE" 2>/dev/null || true
fi
fi
if [ "$IS_IMPORTANT" = "true" ]; then
case "$FILE_PATH" in
*Plans.md*)
echo "📋 Plans.md が更新されました"
;;
*CLAUDE.md*)
echo "📝 CLAUDE.md が更新されました"
;;
*AGENTS.md*)
echo "📝 AGENTS.md が更新されました"
;;
*.test.*|*.spec.*|*__tests__*)
echo "🧪 テストファイルが更新されました: $(basename "$FILE_PATH")"
;;
esac
fi
WORK_FILE=".claude/state/work-active.json"
if [ ! -f "$WORK_FILE" ]; then
WORK_FILE=".claude/state/ultrawork-active.json"
fi
if [ -f "$WORK_FILE" ] && command -v jq >/dev/null 2>&1; then
CURRENT_STATUS=$(jq -r '.review_status // "pending"' "$WORK_FILE" 2>/dev/null)
if [ "$CURRENT_STATUS" = "passed" ] || [ "$CURRENT_STATUS" = "failed" ]; then
TEMP_UW=$(mktemp 2>/dev/null)
if [ -n "$TEMP_UW" ]; then
if jq '.review_status = "pending"' "$WORK_FILE" > "$TEMP_UW" 2>/dev/null; then
mv "$TEMP_UW" "$WORK_FILE" 2>/dev/null || rm -f "$TEMP_UW"
echo "⚠️ work: コード変更を検出 → review_status を pending にリセット(再レビュー必須)" >&2
else
rm -f "$TEMP_UW"
fi
fi
fi
fi
exit 0