This document describes all startup scripts and service files for the HLS webhook handler.
The HLS webhook handler can be started in several ways:
- Development: Using
services/scripts/start-webhook.shwith pm2 or nohup - Production: Using systemd services via
services/scripts/install-services.sh - Manual: Direct webhook command execution
- Purpose: Start the webhook service on port 9000
- Location:
/home/clide/hls/services/scripts/start-webhook.sh - Features:
- Checks if service is already running
- Prefers pm2 if available (better process management)
- Falls back to nohup for background execution
- Creates log files in
logs/directory
- Purpose: Stop the running webhook service
- Location:
/home/clide/hls/services/scripts/stop-webhook.sh - Features:
- Handles both pm2 and direct process termination
- Verifies service is running before attempting stop
- Provides clear status messages
- Purpose: Install and configure systemd services
- Location:
/home/clide/hls/services/scripts/install-services.sh - Requires: sudo privileges
- Actions:
- Copies service files to
/etc/systemd/system/ - Reloads systemd daemon
- Enables services for auto-start on boot
- Starts both github-webhook and hls-fastapi services
- Shows service status and log commands
- Copies service files to
- Purpose: Verify services are running correctly
- Location:
/home/clide/hls/services/scripts/test-services.sh - Checks:
- Systemd service status
- Port availability (9000 and 8000)
- Health endpoint responses
- Recent log entries
- Purpose: Cron job wrapper for analyzing missed issues
- Location:
/home/clide/hls/scripts/cron_analyze_issues.sh - Features:
- Sets up proper environment
- Activates virtual environment
- Implements lock file to prevent concurrent runs
- Comprehensive logging
- Runs
analyze_missed_issues.py
- Purpose: Main webhook receiver service
- Port: 9000
- Features:
- Enhanced security (ProtectSystem, PrivateTmp)
- Automatic restart on failure
- Logs to systemd journal
- Runs as user 'clide'
- Purpose: Optional FastAPI service for direct API access
- Port: 8000
- Features:
- Uses uvicorn ASGI server
- Provides REST API endpoints
- Health check at
/health - Optional component (not required for webhook processing)
- Purpose: Webhook service configuration
- Key Settings:
- Trigger rules for different GitHub events
- Executes
webhook_dispatch.pyon receipt - Passes GitHub headers as environment variables
- Stdin receives full JSON payload
- Purpose: pm2 process manager configuration
- Alternative to: systemd services
- Features:
- Process monitoring and auto-restart
- Log rotation
- Resource monitoring
cd /home/clide/hls
./start-webhook.shcd /home/clide/hls
sudo ./services/install-services.shcd /home/clide/hls
webhook -hooks services/hooks.json -port 9000 -verbosedocker-compose up -dGitHub Webhook → Nginx Proxy Manager → Port 9000 → webhook service → webhook_dispatch.py
(https://clidecoder.com/hooks/github-webhook) (/github-webhook) ↓
Python handlers
↓
Claude AI
(with repo context)
↓
GitHub API
The webhook service is configured to work with Nginx Proxy Manager (NPM) which strips URL prefixes:
- GitHub webhook URL:
https://clidecoder.com/hooks/github-webhook - NPM strips
/hooks: Forwards tohttp://localhost:9000/github-webhook - Webhook service: Configured with
-urlprefix ""to serve at root path
The webhook service uses the -urlprefix "" flag to handle path stripping:
/usr/bin/webhook -hooks /home/clide/hls/hooks.json -port 9000 -verbose -urlprefix ""Important: If using a different proxy setup that preserves paths, remove the -urlprefix "" flag.
The webhook handler executes Claude Code from within specific repository directories to provide proper code context.
repositories:
- name: "clidecoder/hls"
enabled: true
local_path: "/home/clide/hls" # Local repository directory
events:
- "issues"
- "pull_request"
labels:
auto_apply: true
comments:
auto_post: true- Repository Context: Claude Code has access to the full codebase
- CLAUDE.md Files: Project-specific instructions are loaded
- Multi-Project Support: Different repositories can have different local paths
To add support for additional repositories:
-
Clone the repository locally:
git clone https://github.com/owner/repo-name /path/to/local/repo
-
Add to config/settings.yaml:
repositories: - name: "owner/repo-name" enabled: true local_path: "/path/to/local/repo" events: ["issues", "pull_request"]
-
Restart the service:
sudo systemctl restart github-webhook
-
Configure GitHub webhook to point to:
https://clidecoder.com/hooks/github-webhook
# For systemd services
sudo systemctl status github-webhook
sudo systemctl status hls-fastapi
# For pm2
pm2 status
# For manual processes
ps aux | grep webhook# Systemd logs
sudo journalctl -u github-webhook -f
sudo journalctl -u hls-fastapi -f
# pm2 logs
pm2 logs github-webhook
# File logs
tail -f logs/webhook.log
tail -f logs/webhook.err# Webhook service (no direct HTTP endpoint)
curl http://localhost:9000/hooks # Will return 405 without proper webhook
# FastAPI service (if running)
curl http://localhost:8000/health- Check if port is already in use:
sudo lsof -i :9000 - Verify webhook binary exists:
which webhook - Check permissions on scripts:
ls -la *.sh - Review logs for errors
-
Check URL Configuration:
- GitHub webhook URL:
https://clidecoder.com/hooks/github-webhook - Verify NPM strips
/hookscorrectly - Test locally:
curl -X POST http://localhost:9000/github-webhook
- GitHub webhook URL:
-
Verify Service Configuration:
- Ensure
-urlprefix ""flag is set for NPM - Check webhook secret matches GitHub
- Verify repository is configured in settings.yaml
- Ensure
-
Test Repository Context:
# Verify local path exists and is accessible ls -la /home/clide/hls # Check if Claude Code works from the directory cd /home/clide/hls && claude --version
-
Check Logs:
# Service logs sudo journalctl -u github-webhook -f # Webhook processing logs tail -f logs/webhook.log
- Ensure scripts are executable:
chmod +x *.sh - Service files need root to install
- Log directories must be writable by service user
- Repository local_path must be readable by service user
-
Webhook Secret Mismatch:
- Verify
GITHUB_WEBHOOK_SECRETin .env matches GitHub - Check signature validation in logs
- Verify
-
Path Issues:
- Ensure URL ends with
/github-webhook - Verify Content-Type is
application/json
- Ensure URL ends with
-
Repository Not Configured:
- Add repository to config/settings.yaml
- Restart service after configuration changes
To set up automatic issue analysis:
# Add to crontab
crontab -e
# Run every 6 hours
0 */6 * * * /home/clide/hls/scripts/cron_analyze_issues.shTo automatically accept repository collaboration invitations:
# Add to crontab
crontab -e
# Run every 10 minutes (or adjust based on your needs)
*/10 * * * * /home/clide/hls/scripts/cron_auto_accept_invitations.shConfigure invitation acceptance criteria in config/settings.yaml:
auto_accept_invitations:
enabled: true
check_interval_minutes: 10
log_level: "INFO"
criteria:
# Accept invitations to any repository by default
repository_patterns: ["*"]
# Optional: Only accept from specific organizations
# from_organizations: ["trusted-org", "my-company"]
# Optional: Only accept from specific users
# from_users: ["trusted-user", "bot-account"]
# Optional: Exclude certain repositories
# exclude_patterns: ["private-*", "test-*"]Test the invitation processing manually:
# Dry run to see what would happen
python scripts/auto_accept_invitations.py --dry-run
# Process invitations for real
python scripts/auto_accept_invitations.py
# Use custom configuration
python scripts/auto_accept_invitations.py --config path/to/settings.yaml- Webhook Secret: Always use GITHUB_WEBHOOK_SECRET in production
- File Permissions: Keep service files readable only by root
- API Keys: Store in .env file, never commit to repository
- Network: Consider firewall rules for webhook endpoint
- Logs: May contain sensitive data, secure appropriately