mirror of
https://github.com/supabase/supabase.git
synced 2026-05-06 08:56:46 -04:00
chore(studio): add PostToolUse hook to auto-format and lint studio files (#44350)
Adds a Claude Code `PostToolUse` hook that automatically runs prettier and ESLint `--fix` on `apps/studio/` files after every Write or Edit. **Added:** - `.claude/scripts/format_and_lint.sh` — standalone script that receives hook JSON on stdin, extracts the file path, and runs prettier + ESLint - `PostToolUse` hook in `.claude/settings.json` pointing to the script ## Approaches considered **`if` field with path globs (didn't work):** Claude Code hooks support an `if` field that uses permission rule syntax to filter when a hook fires. We tried `"if": "Edit(/apps/studio/**)|Write(/apps/studio/**)"` and variants (`/apps/studio/**`, `apps/studio/**`, single patterns without `|`) to scope the hook to studio files without spawning a process. None of these matched – the `if` field works for tool-name-only matching (`"Edit"`) and Bash command patterns (`"Bash(git *)"`) but does **not** support file path globs for Write/Edit tools. **`$CLAUDE_TOOL_INPUT_FILE_PATH` env var (doesn't exist):** We also tried using `$CLAUDE_TOOL_INPUT_FILE_PATH` to avoid jq parsing of stdin. This env var is not provided by Claude Code – hook input comes exclusively via stdin JSON. The only project-related env var available is `$CLAUDE_PROJECT_DIR`. **Inline shell pipeline (worked but hard to maintain):** The first working version had the full jq + case pipeline inline in settings.json. Copilot review flagged this for readability, error suppression, and the jq dependency – so we extracted it to a script. **Final approach — script with jq stdin parsing + shell `case`:** `.claude/scripts/format_and_lint.sh` extracts the file path from stdin JSON with `jq`, gates on `*apps/studio/*` via `case`, runs prettier on all matched files, then ESLint `--fix` on `.ts/.tsx/.js/.jsx` only. Uses `set -euo pipefail` so prettier/eslint errors surface instead of being swallowed. ## To test - Open a Claude Code session in this repo - Edit any file under `apps/studio/` – should see "Formatting & linting..." spinner - Verify prettier formatting is applied (e.g. introduce extra blank lines, they get collapsed) - Verify ESLint autofixes run on `.ts`/`.tsx`/`.js`/`.jsx` files - Editing files outside `apps/studio/` should not trigger formatting --------- Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Executable
+29
@@ -0,0 +1,29 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# PostToolUse hook: format and lint apps/studio/ files after Write or Edit.
|
||||
# Receives hook JSON on stdin from Claude Code.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Extract the file path from stdin JSON.
|
||||
# Falls back to .tool_response.filePath for Write tool compat.
|
||||
file_path=$(jq -r '.tool_input.file_path // .tool_response.filePath' 2>/dev/null)
|
||||
|
||||
if [[ -z "$file_path" || "$file_path" == "null" ]]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Only run for files under apps/studio/
|
||||
case "$file_path" in
|
||||
*apps/studio/*)
|
||||
cd "$CLAUDE_PROJECT_DIR"
|
||||
pnpm exec prettier --config prettier.config.mjs --write "$file_path"
|
||||
|
||||
# ESLint only for JS/TS files
|
||||
case "$file_path" in
|
||||
*.ts|*.tsx|*.js|*.jsx)
|
||||
pnpm --filter=studio exec eslint --fix "$file_path"
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
@@ -10,6 +10,18 @@
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"PostToolUse": [
|
||||
{
|
||||
"matcher": "Write|Edit",
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/scripts/format_and_lint.sh",
|
||||
"statusMessage": "Formatting & linting..."
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user