mirror of
https://github.com/Donchitos/Claude-Code-Game-Studios.git
synced 2026-10-16 09:58:36 +00:00
Release 1.1.2 — the default path works end to end
Fix release for 1.1.1: the minimal path end to end, engine commands that run on Godot, Unity and Unreal, hook warnings you can see, and verdicts that say when they could not check. Details in CHANGELOG.md; upgrade steps in UPGRADING.md (v1.1.1 → v1.1.2). Fixes #67 Fixes #131 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WuJn2FdynEybfL5KC697nJ
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
7ed2c3e9c4
commit
b21fa0f7f2
@@ -28,11 +28,12 @@ fi
|
||||
[ -n "$CCGS_ROOT" ] && cd "$CCGS_ROOT" 2>/dev/null || true
|
||||
|
||||
# Claude Code PostToolUse hook: Validates asset files after Write/Edit
|
||||
# Checks naming conventions for files in assets/ directory
|
||||
# Checks JSON validity of data files and, in Godot's assets/, naming conventions.
|
||||
# Asset roots per engine: Godot assets/, Unity Assets/, Unreal Content/.
|
||||
#
|
||||
# Exit behavior:
|
||||
# exit 0 = success or advisory warnings only
|
||||
# exit 2 = build-breaking issue (invalid JSON, missing required fields)
|
||||
# exit 2 = build-breaking issue (a data file that is not valid JSON)
|
||||
#
|
||||
# A PostToolUse hook CANNOT block -- the write has already happened by the time
|
||||
# this runs (see .claude/docs/hooks-reference/hook-input-schemas.md). The only
|
||||
@@ -64,60 +65,98 @@ fi
|
||||
# validates nothing on Windows.
|
||||
FILE_PATH=$(printf '%s' "$FILE_PATH" | sed 's|\\\\|/|g; s|\\|/|g')
|
||||
|
||||
# Only check files in assets/
|
||||
if ! echo "$FILE_PATH" | grep -qE '(^|/)assets/'; then
|
||||
exit 0
|
||||
fi
|
||||
# Make the path project-relative. Claude Code sends a file tool's path
|
||||
# ABSOLUTE, with native separators (C:\... on Windows), so an unanchored
|
||||
# `(^|/)assets/` matched every file in a project with any parent folder named
|
||||
# assets, and node_modules/*/assets/ too. Strip the project root in either
|
||||
# spelling Git Bash gives it (/c/Users/... from pwd, C:/Users/... from pwd -W,
|
||||
# drive letter in either case); a path still absolute is outside the project.
|
||||
_VA_ROOT=$(pwd); _VA_ROOT_W=$(pwd -W 2>/dev/null || printf '%s' "$_VA_ROOT")
|
||||
shopt -s nocasematch
|
||||
case "$FILE_PATH" in
|
||||
"$_VA_ROOT"/*) REL_PATH="${FILE_PATH:${#_VA_ROOT}+1}" ;;
|
||||
"$_VA_ROOT_W"/*) REL_PATH="${FILE_PATH:${#_VA_ROOT_W}+1}" ;;
|
||||
/*|[A-Za-z]:/*) exit 0 ;;
|
||||
*) REL_PATH="${FILE_PATH#./}" ;;
|
||||
esac
|
||||
shopt -u nocasematch
|
||||
|
||||
FILENAME=$(basename "$FILE_PATH")
|
||||
# Only check files under an asset root.
|
||||
case "$REL_PATH" in
|
||||
assets/*|Assets/*|Content/*) ;;
|
||||
*) exit 0 ;;
|
||||
esac
|
||||
|
||||
FILENAME=$(basename "$REL_PATH")
|
||||
WARNINGS="" # Style/convention issues -- exit 0 with advisory message
|
||||
ERRORS="" # Build-breaking issues -- exit 1 to block the operation
|
||||
ERRORS="" # Build-breaking issues -- exit 2 so Claude hears about it
|
||||
|
||||
# ADVISORY: Check naming convention (lowercase with underscores only)
|
||||
# Naming issues are style violations -- warn but do not block
|
||||
# ADVISORY: naming convention -- lowercase with underscores, the Godot
|
||||
# convention, so only in Godot's assets/. Unity and Unreal name assets in
|
||||
# PascalCase with type prefixes; warning on every one of them trains the user
|
||||
# to ignore this hook. Naming issues warn, never block.
|
||||
# Uses grep -E (POSIX) not grep -P (Perl) for Windows Git Bash compatibility
|
||||
if echo "$FILENAME" | grep -qE '[A-Z[:space:]-]'; then
|
||||
WARNINGS="$WARNINGS\n NAMING: $FILE_PATH must be lowercase with underscores (got: $FILENAME)"
|
||||
fi
|
||||
case "$REL_PATH" in
|
||||
assets/*)
|
||||
if echo "$FILENAME" | grep -qE '[A-Z[:space:]-]'; then
|
||||
WARNINGS="$WARNINGS\n NAMING: $REL_PATH must be lowercase with underscores (got: $FILENAME)"
|
||||
fi ;;
|
||||
esac
|
||||
|
||||
# BLOCKING: Check JSON validity for data files
|
||||
# BLOCKING: Check JSON validity for data files, in any engine's data folder --
|
||||
# the same set validate-commit.sh blocks on.
|
||||
# Invalid JSON will break runtime loading -- this is a build-breaking error
|
||||
if echo "$FILE_PATH" | grep -qE '(^|/)assets/data/.*\.json$'; then
|
||||
if echo "$REL_PATH" | grep -qE '^(assets|Assets|Content)/(.*/)?[Dd]ata/.*\.[Jj][Ss][Oo][Nn]$'; then
|
||||
FILE_PATH="$REL_PATH"
|
||||
if [ -f "$FILE_PATH" ]; then
|
||||
# Find a working Python command
|
||||
PYTHON_CMD=""
|
||||
# Run it, do not just find it: the Windows Store `python` placeholder
|
||||
# passes `command -v`, then fails, and valid JSON was reported invalid.
|
||||
for cmd in python python3 py; do
|
||||
if command -v "$cmd" >/dev/null 2>&1; then
|
||||
if command -v "$cmd" >/dev/null 2>&1 && "$cmd" -c 'import sys; sys.exit(sys.version_info[0] < 3)' >/dev/null 2>&1; then
|
||||
PYTHON_CMD="$cmd"
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -n "$PYTHON_CMD" ]; then
|
||||
if ! "$PYTHON_CMD" -m json.tool "$FILE_PATH" > /dev/null 2>&1; then
|
||||
# utf-8-sig, as validate-commit.sh reads it: `json.tool` rejected a
|
||||
# file with a UTF-8 BOM that the commit check then accepted.
|
||||
if ! "$PYTHON_CMD" -c 'import json, sys; json.load(open(sys.argv[1], encoding="utf-8-sig"))' "$FILE_PATH" > /dev/null 2>&1; then
|
||||
ERRORS="$ERRORS\n FORMAT: $FILE_PATH is not valid JSON — fix syntax errors before continuing"
|
||||
fi
|
||||
else
|
||||
# Say so rather than skipping in silence. This is the only BLOCKING
|
||||
# check in this hook, so without an interpreter the hook exits 0 on
|
||||
# a file it never opened -- indistinguishable from valid JSON. The
|
||||
# sibling validate-commit.sh already warns in exactly this case;
|
||||
# this half was the one that did not.
|
||||
echo "WARNING: Cannot validate JSON (python not found) — $FILE_PATH unchecked" >&2
|
||||
# sibling validate-commit.sh blocks in this case; this half, which
|
||||
# runs after the file is written, says so instead.
|
||||
WARNINGS="$WARNINGS\n UNCHECKED: cannot validate JSON (python not found) — $FILE_PATH"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# Report warnings (advisory -- non-blocking)
|
||||
if [ -n "$WARNINGS" ]; then
|
||||
echo -e "=== Asset Validation: Warnings ===$WARNINGS\n==================================\n(Warnings are advisory. Fix before final commit.)" >&2
|
||||
fi
|
||||
|
||||
# Report build-breaking issues. exit 2 routes this to Claude, not just the user,
|
||||
# so the file that was already written can actually be corrected.
|
||||
# so the file that was already written can actually be corrected. Any warnings
|
||||
# ride along on the same channel.
|
||||
if [ -n "$ERRORS" ]; then
|
||||
echo -e "=== Asset Validation: ERRORS ===$ERRORS\n================================\nThe file was written but is broken. Fix it now, before continuing." >&2
|
||||
[ -n "$WARNINGS" ] && echo -e "=== Asset Validation: Warnings ===$WARNINGS" >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
# Warnings alone do not need a fix now, but they must be seen: stderr on exit 0
|
||||
# reaches the debug log only. Hook JSON reaches the user and Claude -- see
|
||||
# hook_warn in yaml-helper.sh. stderr stays as the fallback without the helper.
|
||||
if [ -n "$WARNINGS" ]; then
|
||||
_VA_MSG=$(echo -e "=== Asset Validation: Warnings ===$WARNINGS\n==================================\n(Warnings are advisory. Fix before final commit.)")
|
||||
[ -f .claude/hooks/yaml-helper.sh ] && . .claude/hooks/yaml-helper.sh 2>/dev/null
|
||||
if command -v hook_warn >/dev/null 2>&1; then
|
||||
hook_warn PostToolUse "$_VA_MSG"
|
||||
else
|
||||
printf '%s\n' "$_VA_MSG" >&2
|
||||
fi
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
||||
Reference in New Issue
Block a user