Skip to content

Commit fb5c697

Browse files
authored
chore: add Claude Code hooks for file protection (#3391)
1 parent ef1d3ef commit fb5c697

4 files changed

Lines changed: 89 additions & 1 deletion

File tree

.claude/hooks/auto-lint.sh

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#!/bin/bash
2+
# Auto-lint TypeScript files after edits
3+
# Runs eslint --fix on the edited file for fast, single-file linting
4+
5+
set -euo pipefail
6+
7+
# Read input from stdin
8+
input_data=$(cat)
9+
10+
file_path=$(echo "$input_data" | jq -r '.tool_input.file_path // empty')
11+
12+
# If no file path or not a TypeScript file, skip
13+
if [[ -z "$file_path" ]] || [[ ! "$file_path" == *.ts ]]; then
14+
exit 0
15+
fi
16+
17+
# Only lint if file exists (skip for failed writes)
18+
if [[ ! -f "$file_path" ]]; then
19+
exit 0
20+
fi
21+
22+
# Run eslint fix on the single file (suppress errors to avoid blocking)
23+
cd "$CLAUDE_PROJECT_DIR" && pnpm eslint --fix "$file_path" 2>/dev/null || true
24+
25+
exit 0

.claude/hooks/protect-files.sh

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#!/bin/bash
2+
# Prevent modification of sensitive files that should be edited manually
3+
# Exit code 2 blocks the tool and shows the message to Claude
4+
5+
set -euo pipefail
6+
7+
# Read input from stdin
8+
input_data=$(cat)
9+
10+
file_path=$(echo "$input_data" | jq -r '.tool_input.file_path // empty')
11+
12+
# If no file path, allow the operation
13+
if [[ -z "$file_path" ]]; then
14+
exit 0
15+
fi
16+
17+
# List of protected file patterns
18+
protected_patterns=(
19+
"pnpm-lock.yaml"
20+
".infra/Pulumi."
21+
"src/migration/"
22+
".env"
23+
".git/"
24+
)
25+
26+
for pattern in "${protected_patterns[@]}"; do
27+
if [[ "$file_path" == *"$pattern"* ]]; then
28+
echo "Protected file: $file_path - this file should be edited manually" >&2
29+
exit 2
30+
fi
31+
done
32+
33+
exit 0

.claude/settings.json

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"hooks": {
3+
"PreToolUse": [
4+
{
5+
"matcher": "Edit|Write",
6+
"hooks": [
7+
{
8+
"type": "command",
9+
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/protect-files.sh"
10+
}
11+
]
12+
}
13+
],
14+
"PostToolUse": [
15+
{
16+
"matcher": "Edit|Write",
17+
"hooks": [
18+
{
19+
"type": "command",
20+
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/auto-lint.sh"
21+
}
22+
]
23+
}
24+
]
25+
}
26+
}

AGENTS.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,4 +102,8 @@ This file provides guidance to coding agents when working with code in this repo
102102
- `.infra/` - Pulumi configuration for deployment
103103
- `.infra/crons.ts` - Cron job schedules and resource limits
104104
- `.infra/common.ts` - Worker subscription definitions
105-
- `.infra/index.ts` - Main Pulumi deployment configuration
105+
- `.infra/index.ts` - Main Pulumi deployment configuration
106+
107+
## Pull Requests
108+
109+
Keep PR descriptions concise and to the point. Reviewers should not be exhausted by lengthy explanations.

0 commit comments

Comments
 (0)