This guide covers installation on macOS, Linux, Docker, and Raspberry Pi.
All platforms:
- Python 3.11 or newer (download here)
- OpenClaw installed with webhooks enabled
- Terminal/command line access
Verify Python version:
python3 --version # Should show 3.11.x or higher# 1. Clone repository
git clone https://github.com/astra-ventures/pulse.git
cd pulse
# 2. Install
pip3 install -e .
# 3. Copy example config (recommended location)
mkdir -p ~/.pulse/config
cp config/pulse.example.yaml ~/.pulse/config/pulse.yaml
# 4. Edit config (set your webhook URL + token)
nano ~/.pulse/config/pulse.yaml # or use your preferred editor
# 5. Run Pulse
python3 -m pulse
# 6. Verify (in another terminal)
curl http://localhost:9720/healthExpected output:
{"status": "healthy", "uptime": 42}Option 1: Run manually
cd /path/to/pulse
python3 -m pulseOption 2: Run as LaunchAgent (starts on login)
- Create LaunchAgent plist:
cat > ~/Library/LaunchAgents/ai.iris.pulse.plist <<EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>ai.iris.pulse</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/bin/python3</string>
<string>-m</string>
<string>pulse</string>
</array>
<key>WorkingDirectory</key>
<string>/Users/YOUR_USERNAME/pulse</string>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
<key>StandardOutPath</key>
<string>/Users/YOUR_USERNAME/pulse/pulse.log</string>
<key>StandardErrorPath</key>
<string>/Users/YOUR_USERNAME/pulse/pulse.error.log</string>
</dict>
</plist>
EOF- Update paths:
# Replace YOUR_USERNAME with your actual username
sed -i '' 's/YOUR_USERNAME/'"$USER"'/g' ~/Library/LaunchAgents/ai.iris.pulse.plist- Load and start:
launchctl load ~/Library/LaunchAgents/ai.iris.pulse.plist
launchctl start ai.iris.pulse- Verify:
launchctl list | grep pulse
curl http://localhost:9720/healthTo stop:
launchctl stop ai.iris.pulse
launchctl unload ~/Library/LaunchAgents/ai.iris.pulse.plistOption 1: Run manually
cd /path/to/pulse
python3 -m pulseOption 2: Run as systemd service (starts on boot)
- Create service file:
sudo nano /etc/systemd/system/pulse.service- Paste this content (update paths):
[Unit]
Description=Pulse Autonomous Agent Daemon
After=network.target
[Service]
Type=simple
User=YOUR_USERNAME
WorkingDirectory=/home/YOUR_USERNAME/pulse
ExecStart=/usr/bin/python3 -m pulse
Restart=always
RestartSec=10
StandardOutput=append:/home/YOUR_USERNAME/pulse/pulse.log
StandardError=append:/home/YOUR_USERNAME/pulse/pulse.error.log
[Install]
WantedBy=multi-user.target- Replace YOUR_USERNAME:
sudo sed -i 's/YOUR_USERNAME/'"$USER"'/g' /etc/systemd/system/pulse.service- Enable and start:
sudo systemctl daemon-reload
sudo systemctl enable pulse
sudo systemctl start pulse- Verify:
sudo systemctl status pulse
curl http://localhost:9720/healthTo stop:
sudo systemctl stop pulse
sudo systemctl disable pulseWhy Docker?
- Portable across machines (easy migration)
- Isolated environment (no dependency conflicts)
- Easy updates (
docker pull+ restart)
Build image:
cd pulse
docker build -t pulse:latest .Run container:
docker run -d \
--name pulse \
--restart unless-stopped \
-v $(pwd)/config:/app/config \
-v $(pwd)/state:/app/state \
-p 9720:9720 \
pulse:latestVerify:
docker logs pulse
curl http://localhost:9720/healthUpdate:
docker stop pulse
docker rm pulse
git pull
docker build -t pulse:latest .
docker run -d ... (same command as above)Migrate to another machine:
# On old machine:
docker save pulse:latest | gzip > pulse-image.tar.gz
tar -czf pulse-data.tar.gz config/ state/
# Copy files to new machine, then:
docker load < pulse-image.tar.gz
tar -xzf pulse-data.tar.gz
docker run -d ... (same command as above)Recommended: Pi 4 (4GB+ RAM) or Pi 5
Install Python 3.11:
# Update system
sudo apt update && sudo apt upgrade -y
# Install Python 3.11
sudo apt install python3.11 python3.11-venv python3-pip -y
# Verify
python3.11 --versionInstall Pulse:
# Clone
git clone https://github.com/astra-ventures/pulse.git
cd pulse
# Create virtual environment (recommended for Pi)
python3.11 -m venv venv
source venv/bin/activate
# Install
pip install -e .
# Configure
cp config/pulse.example.yaml ~/.pulse/config/pulse.yaml
nano ~/.pulse/config/pulse.yaml
# Run
python3 -m pulseRun as systemd service: Follow Linux systemd instructions above, but use:
ExecStart=/home/YOUR_USERNAME/pulse/venv/bin/python -m pulsePerformance tips:
- Use
evaluator.mode: "rules"(avoids AI calls) - Increase
sensors.filesystem.poll_interval(reduce CPU) - Limit
openclaw.max_turns_per_hour(conserve resources)
Minimal config (config/pulse.yaml):
openclaw:
webhook_url: "http://localhost:8080/hooks/agent"
webhook_token: "your-webhook-token-here"Find your webhook token:
cat ~/.openclaw/config.yaml | grep webhookTokenTest configuration:
python3 -m pulse doctorSolution: Install dependencies:
pip3 install -e .Solution: Pulse isn't running. Check:
# Manual run
ps aux | grep pulse
# systemd (Linux)
sudo systemctl status pulse
# LaunchAgent (Mac)
launchctl list | grep pulse
# Docker
docker ps | grep pulseSolution: Wrong webhook token. Update config/pulse.yaml:
openclaw:
webhook_token: "correct-token-from-openclaw-config"Solution: Reduce polling frequency:
sensors:
filesystem:
poll_interval: 600 # 10 minutes instead of 1Solution: Increase thresholds and cooldowns:
drives:
trigger_threshold: 8.0 # Higher = less sensitive
openclaw:
min_trigger_interval: 3600 # 1 hour cooldown
max_turns_per_hour: 4 # Cap at 4 triggers/hourSolution: Lower threshold or check drive sources exist:
drives:
trigger_threshold: 3.0 # Lower = more sensitive
categories:
goals:
sources:
- "goals.json" # Make sure this file exists!- Read the docs:
docs/architecture.mdexplains how Pulse works - Check examples:
examples/has ready-to-use configs - Tune your config: See
docs/configuration.mdfor all options - Monitor behavior: Check
pulse.logand/stateendpoint
Manual install:
rm -rf /path/to/pulseLaunchAgent (Mac):
launchctl unload ~/Library/LaunchAgents/ai.iris.pulse.plist
rm ~/Library/LaunchAgents/ai.iris.pulse.plistsystemd (Linux):
sudo systemctl stop pulse
sudo systemctl disable pulse
sudo rm /etc/systemd/system/pulse.service
sudo systemctl daemon-reloadDocker:
docker stop pulse
docker rm pulse
docker rmi pulse:latest- GitHub Issues: github.com/astra-ventures/pulse/issues
- Discord: OpenClaw community (#pulse channel)
- Docs: docs/
Happy automating! 🔮