Initial commit
This commit is contained in:
114
hooks/notification.py
Executable file
114
hooks/notification.py
Executable file
@@ -0,0 +1,114 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
import random
|
||||
from pathlib import Path
|
||||
|
||||
try:
|
||||
from dotenv import load_dotenv
|
||||
load_dotenv()
|
||||
except ImportError:
|
||||
pass # dotenv is optional
|
||||
|
||||
|
||||
def get_tts_script_path():
|
||||
"""
|
||||
Determine which TTS script to use - only pyttsx3 is available.
|
||||
"""
|
||||
# Get current script directory and construct utils/tts path
|
||||
script_dir = Path(__file__).parent
|
||||
tts_dir = script_dir / "utils" / "tts"
|
||||
|
||||
# Use pyttsx3 (no API key required)
|
||||
pyttsx3_script = tts_dir / "pyttsx3_tts.py"
|
||||
if pyttsx3_script.exists():
|
||||
return str(pyttsx3_script)
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def announce_notification():
|
||||
"""Announce that the agent needs user input."""
|
||||
try:
|
||||
tts_script = get_tts_script_path()
|
||||
if not tts_script:
|
||||
return # No TTS scripts available
|
||||
|
||||
# Get engineer name if available
|
||||
engineer_name = os.getenv('ENGINEER_NAME', '').strip()
|
||||
|
||||
# Create notification message with 30% chance to include name
|
||||
if engineer_name and random.random() < 0.3:
|
||||
notification_message = f"{engineer_name}, your agent needs your input"
|
||||
else:
|
||||
notification_message = "Your agent needs your input"
|
||||
|
||||
# Call the TTS script with the notification message
|
||||
subprocess.run([
|
||||
"python3", tts_script, notification_message
|
||||
],
|
||||
capture_output=True, # Suppress output
|
||||
timeout=10 # 10-second timeout
|
||||
)
|
||||
|
||||
except (subprocess.TimeoutExpired, subprocess.SubprocessError, FileNotFoundError):
|
||||
# Fail silently if TTS encounters issues
|
||||
pass
|
||||
except Exception:
|
||||
# Fail silently for any other errors
|
||||
pass
|
||||
|
||||
|
||||
def main():
|
||||
try:
|
||||
# Parse command line arguments
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('--notify', action='store_true', help='Enable TTS notifications')
|
||||
args = parser.parse_args()
|
||||
|
||||
# Read JSON input from stdin
|
||||
input_data = json.loads(sys.stdin.read())
|
||||
|
||||
# Ensure log directory exists
|
||||
import os
|
||||
log_dir = os.path.join(os.getcwd(), '.claude', 'logs')
|
||||
os.makedirs(log_dir, exist_ok=True)
|
||||
log_file = os.path.join(log_dir, 'notification.json')
|
||||
|
||||
# Read existing log data or initialize empty list
|
||||
if os.path.exists(log_file):
|
||||
with open(log_file, 'r') as f:
|
||||
try:
|
||||
log_data = json.load(f)
|
||||
except (json.JSONDecodeError, ValueError):
|
||||
log_data = []
|
||||
else:
|
||||
log_data = []
|
||||
|
||||
# Append new data
|
||||
log_data.append(input_data)
|
||||
|
||||
# Write back to file with formatting
|
||||
with open(log_file, 'w') as f:
|
||||
json.dump(log_data, f, indent=2)
|
||||
|
||||
# Announce notification via TTS only if --notify flag is set
|
||||
# Skip TTS for the generic "Claude is waiting for your input" message
|
||||
if args.notify and input_data.get('message') != 'Claude is waiting for your input':
|
||||
announce_notification()
|
||||
|
||||
sys.exit(0)
|
||||
|
||||
except json.JSONDecodeError:
|
||||
# Handle JSON decode errors gracefully
|
||||
sys.exit(0)
|
||||
except Exception:
|
||||
# Handle any other errors gracefully
|
||||
sys.exit(0)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Reference in New Issue
Block a user