Add dotclaude configuration files
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,125 @@
|
||||
#!/bin/bash
|
||||
# Auto-formats files after Claude edits them.
|
||||
# Used as a PostToolUse hook for Edit|Write operations.
|
||||
# Auto-detects formatters — requires both the binary AND a config file to activate.
|
||||
|
||||
# Requires jq for JSON parsing
|
||||
if ! command -v jq >/dev/null 2>&1; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
INPUT=$(cat)
|
||||
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')
|
||||
|
||||
if [ -z "$FILE_PATH" ] || [ ! -f "$FILE_PATH" ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
EXTENSION="${FILE_PATH##*.}"
|
||||
FORMATTED=false
|
||||
|
||||
# Find the project root (nearest directory with package.json, pyproject.toml, Cargo.toml, go.mod, or .git)
|
||||
find_project_root() {
|
||||
local dir="$PWD"
|
||||
while [ "$dir" != "/" ]; do
|
||||
if [ -f "$dir/package.json" ] || [ -f "$dir/pyproject.toml" ] || [ -f "$dir/Cargo.toml" ] || [ -f "$dir/go.mod" ] || [ -d "$dir/.git" ]; then
|
||||
echo "$dir"
|
||||
return
|
||||
fi
|
||||
dir=$(dirname "$dir")
|
||||
done
|
||||
echo "$PWD"
|
||||
}
|
||||
|
||||
ROOT=$(find_project_root)
|
||||
|
||||
# --- Biome (JS/TS all-in-one — check first, it's faster than Prettier) ---
|
||||
if [ "$FORMATTED" = false ] && [ -f "$ROOT/node_modules/.bin/biome" ] && [ -f "$ROOT/biome.json" -o -f "$ROOT/biome.jsonc" ]; then
|
||||
case "$EXTENSION" in
|
||||
js|jsx|ts|tsx|json|css)
|
||||
npx biome format --write "$FILE_PATH" 2>/dev/null && FORMATTED=true
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# --- Prettier (Node.js / TypeScript) ---
|
||||
if [ "$FORMATTED" = false ] && [ -f "$ROOT/node_modules/.bin/prettier" ]; then
|
||||
# Check for Prettier config (any common format)
|
||||
HAS_PRETTIER_CONFIG=false
|
||||
for cfg in .prettierrc .prettierrc.json .prettierrc.yml .prettierrc.yaml .prettierrc.js .prettierrc.cjs .prettierrc.mjs .prettierrc.toml prettier.config.js prettier.config.cjs prettier.config.mjs; do
|
||||
if [ -f "$ROOT/$cfg" ]; then
|
||||
HAS_PRETTIER_CONFIG=true
|
||||
break
|
||||
fi
|
||||
done
|
||||
# Also check package.json for "prettier" key
|
||||
if [ "$HAS_PRETTIER_CONFIG" = false ] && [ -f "$ROOT/package.json" ] && grep -q '"prettier"' "$ROOT/package.json" 2>/dev/null; then
|
||||
HAS_PRETTIER_CONFIG=true
|
||||
fi
|
||||
|
||||
if [ "$HAS_PRETTIER_CONFIG" = true ]; then
|
||||
case "$EXTENSION" in
|
||||
js|jsx|ts|tsx|json|css|scss|md|yaml|yml|html)
|
||||
npx prettier --write "$FILE_PATH" 2>/dev/null && FORMATTED=true
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
fi
|
||||
|
||||
# --- Ruff (Python — modern replacement for Black + isort) ---
|
||||
if [ "$FORMATTED" = false ] && command -v ruff >/dev/null 2>&1; then
|
||||
HAS_RUFF_CONFIG=false
|
||||
if [ -f "$ROOT/ruff.toml" ] || [ -f "$ROOT/.ruff.toml" ]; then
|
||||
HAS_RUFF_CONFIG=true
|
||||
elif [ -f "$ROOT/pyproject.toml" ] && grep -q '\[tool\.ruff\]' "$ROOT/pyproject.toml" 2>/dev/null; then
|
||||
HAS_RUFF_CONFIG=true
|
||||
fi
|
||||
|
||||
if [ "$HAS_RUFF_CONFIG" = true ]; then
|
||||
case "$EXTENSION" in
|
||||
py)
|
||||
ruff format "$FILE_PATH" 2>/dev/null
|
||||
ruff check --fix "$FILE_PATH" 2>/dev/null
|
||||
FORMATTED=true
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
fi
|
||||
|
||||
# --- Black + isort (Python — fallback if Ruff not configured) ---
|
||||
if [ "$FORMATTED" = false ] && command -v black >/dev/null 2>&1; then
|
||||
HAS_BLACK_CONFIG=false
|
||||
if [ -f "$ROOT/pyproject.toml" ] && grep -q '\[tool\.black\]' "$ROOT/pyproject.toml" 2>/dev/null; then
|
||||
HAS_BLACK_CONFIG=true
|
||||
fi
|
||||
|
||||
if [ "$HAS_BLACK_CONFIG" = true ]; then
|
||||
case "$EXTENSION" in
|
||||
py)
|
||||
black --quiet "$FILE_PATH" 2>/dev/null
|
||||
command -v isort >/dev/null 2>&1 && isort --quiet "$FILE_PATH" 2>/dev/null
|
||||
FORMATTED=true
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
fi
|
||||
|
||||
# --- Rust (rustfmt is standard — no config check needed) ---
|
||||
if [ "$FORMATTED" = false ] && command -v rustfmt >/dev/null 2>&1; then
|
||||
case "$EXTENSION" in
|
||||
rs)
|
||||
rustfmt "$FILE_PATH" 2>/dev/null && FORMATTED=true
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# --- Go (gofmt is standard — no config check needed) ---
|
||||
if [ "$FORMATTED" = false ] && command -v gofmt >/dev/null 2>&1; then
|
||||
case "$EXTENSION" in
|
||||
go)
|
||||
gofmt -w "$FILE_PATH" 2>/dev/null && FORMATTED=true
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
exit 0
|
||||
Reference in New Issue
Block a user