From 2479ac05cff4ad98101c0d4cfa9723e419927fa3 Mon Sep 17 00:00:00 2001 From: wasrusgen Date: Sat, 16 May 2026 11:01:34 +0300 Subject: [PATCH] chore: add Claude Code PostToolUse syntax-check hook MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .claude/settings.json — hook fires after every Edit/Write: - .js files → node --check - .py files → py_compile.compile (doraise=True) - exit 2 on failure → Claude sees the error immediately and fixes it Scripts: - .claude/hooks/syntax_check.ps1 (Windows, primary) - .claude/hooks/syntax_check.sh (bash fallback) Co-Authored-By: Claude Sonnet 4.6 --- .claude/hooks/syntax_check.ps1 | 41 ++++++++++++++++++++++ .claude/hooks/syntax_check.sh | 62 ++++++++++++++++++++++++++++++++++ .claude/settings.json | 15 ++++++++ 3 files changed, 118 insertions(+) create mode 100644 .claude/hooks/syntax_check.ps1 create mode 100644 .claude/hooks/syntax_check.sh create mode 100644 .claude/settings.json diff --git a/.claude/hooks/syntax_check.ps1 b/.claude/hooks/syntax_check.ps1 new file mode 100644 index 0000000..892e224 --- /dev/null +++ b/.claude/hooks/syntax_check.ps1 @@ -0,0 +1,41 @@ +# ================================================================ +# Claude Code — PostToolUse hook (Windows PowerShell fallback) +# Syntax check after every Edit / Write tool call. +# Exit code 2 = Claude sees the error and can fix immediately. +# ================================================================ + +param() + +# Read file_path from CLAUDE_TOOL_INPUT env var (JSON) +$filePath = "" +try { + $input_json = $env:CLAUDE_TOOL_INPUT | ConvertFrom-Json -ErrorAction Stop + $filePath = $input_json.file_path +} catch {} + +if (-not $filePath -or -not (Test-Path $filePath)) { exit 0 } + +$ext = [System.IO.Path]::GetExtension($filePath).TrimStart('.') + +switch ($ext) { + "js" { + $result = & node --check $filePath 2>&1 + if ($LASTEXITCODE -ne 0) { + Write-Output "❌ JS SYNTAX ERROR: $filePath" + Write-Output $result + exit 2 + } + } + "py" { + $escaped = $filePath -replace "'", "''" + $result = & python -c "import py_compile,sys; py_compile.compile('$escaped', doraise=True)" 2>&1 + if ($LASTEXITCODE -ne 0) { + Write-Output "❌ PY SYNTAX ERROR: $filePath" + Write-Output $result + exit 2 + } + } + default { exit 0 } +} + +exit 0 diff --git a/.claude/hooks/syntax_check.sh b/.claude/hooks/syntax_check.sh new file mode 100644 index 0000000..002291f --- /dev/null +++ b/.claude/hooks/syntax_check.sh @@ -0,0 +1,62 @@ +#!/usr/bin/env bash +# ============================================================= +# Claude Code — PostToolUse hook: syntax check after Edit/Write +# Reads tool input JSON from stdin, extracts file_path, +# runs language-appropriate syntax check. +# Exit 2 → Claude sees the error and can fix it immediately. +# ============================================================= + +set -euo pipefail + +# Parse file_path from JSON stdin (jq if available, else python fallback) +if command -v jq &>/dev/null; then + FILE_PATH=$(echo "$CLAUDE_TOOL_INPUT" | jq -r '.file_path // empty' 2>/dev/null || true) +else + FILE_PATH=$(python3 -c " +import sys, json +try: + d = json.loads(sys.stdin.read()) + print(d.get('file_path', '')) +except Exception: + pass +" <<< "$CLAUDE_TOOL_INPUT" 2>/dev/null || true) +fi + +# Also try env var set by Claude Code +FILE_PATH="${FILE_PATH:-${CLAUDE_TOOL_INPUT_FILE_PATH:-}}" + +if [[ -z "$FILE_PATH" || ! -f "$FILE_PATH" ]]; then + exit 0 +fi + +EXT="${FILE_PATH##*.}" + +case "$EXT" in + js) + if ! OUTPUT=$(node --check "$FILE_PATH" 2>&1); then + echo "❌ JS SYNTAX ERROR: $FILE_PATH" + echo "$OUTPUT" + exit 2 + fi + ;; + py) + if ! OUTPUT=$(python3 -c " +import py_compile, sys +try: + py_compile.compile('$FILE_PATH', doraise=True) +except py_compile.PyCompileError as e: + print(e) + sys.exit(1) +" 2>&1); then + echo "❌ PY SYNTAX ERROR: $FILE_PATH" + echo "$OUTPUT" + exit 2 + fi + ;; + *) + # Остальные типы файлов — пропускаем + exit 0 + ;; +esac + +exit 0 diff --git a/.claude/settings.json b/.claude/settings.json new file mode 100644 index 0000000..3da2740 --- /dev/null +++ b/.claude/settings.json @@ -0,0 +1,15 @@ +{ + "hooks": { + "PostToolUse": [ + { + "matcher": "Edit|Write", + "hooks": [ + { + "type": "command", + "command": "powershell -NonInteractive -File \".claude\\hooks\\syntax_check.ps1\"" + } + ] + } + ] + } +}