|
|
@@ -0,0 +1,61 @@
|
|
|
+#!/bin/bash
|
|
|
+# Caffeinate hook: Blocks sleep commands and suggests background tasks
|
|
|
+set -euo pipefail
|
|
|
+
|
|
|
+input=$(cat)
|
|
|
+command=$(echo "$input" | jq -r '.tool_input.command // empty')
|
|
|
+
|
|
|
+if [[ -z "$command" ]]; then
|
|
|
+ exit 0
|
|
|
+fi
|
|
|
+
|
|
|
+# Allow sleep if run_in_background is true - that's the whole point!
|
|
|
+run_in_bg=$(echo "$input" | jq -r '.tool_input.run_in_background // false')
|
|
|
+if [[ "$run_in_bg" == "true" ]]; then
|
|
|
+ exit 0
|
|
|
+fi
|
|
|
+
|
|
|
+block_message='ACTION REQUIRED: Your sleep command was blocked. You MUST now call Bash again with the SAME command but add the parameter run_in_background: true. Do this immediately in your next tool call. Do not explain or apologize - just retry with run_in_background: true.'
|
|
|
+
|
|
|
+output_block() {
|
|
|
+ # Output JSON to stdout for blocking decision
|
|
|
+ # Output message to stderr to feed back to Claude
|
|
|
+ cat << EOF
|
|
|
+{
|
|
|
+ "hookSpecificOutput": {
|
|
|
+ "hookEventName": "PreToolUse",
|
|
|
+ "permissionDecision": "deny",
|
|
|
+ "permissionDecisionReason": "$block_message"
|
|
|
+ }
|
|
|
+}
|
|
|
+EOF
|
|
|
+ exit 0
|
|
|
+}
|
|
|
+
|
|
|
+# Remove all quoted strings to avoid false positives
|
|
|
+# Replace single and double quoted strings with placeholder
|
|
|
+cmd_no_quotes=$(echo "$command" | sed -E "s/\"[^\"]*\"//g; s/'[^']*'//g")
|
|
|
+
|
|
|
+# Check for sleep command patterns in the de-quoted command
|
|
|
+# Pattern 1: Command starts with sleep
|
|
|
+if [[ "$cmd_no_quotes" =~ (^|[[:space:]])sleep[[:space:]]+[0-9] ]]; then
|
|
|
+ output_block
|
|
|
+fi
|
|
|
+
|
|
|
+# Pattern 2: sleep after any common separator (&&, ||, ;, |, do, then)
|
|
|
+if [[ "$cmd_no_quotes" =~ (\&\&|;\||[[:space:]]do[[:space:]]|[[:space:]]then[[:space:]])[[:space:]]*sleep[[:space:]] ]]; then
|
|
|
+ output_block
|
|
|
+fi
|
|
|
+
|
|
|
+# Pattern 3: Simple contains check - if "sleep " followed by number appears anywhere
|
|
|
+if [[ "$cmd_no_quotes" =~ sleep[[:space:]]+[0-9] ]]; then
|
|
|
+ output_block
|
|
|
+fi
|
|
|
+
|
|
|
+# Pattern 4: sleep with variable like $TIMEOUT or ${DELAY}
|
|
|
+if [[ "$cmd_no_quotes" =~ sleep[[:space:]]+\$ ]]; then
|
|
|
+ output_block
|
|
|
+fi
|
|
|
+
|
|
|
+# No sleep command detected - allow
|
|
|
+exit 0
|