A personal focus monitoring system that tracks browser activity and detects when you drift from your goals
Features β’ Quick Start β’ Installation β’ Usage β’ Configuration
β οΈ Platform Support: Currently supports macOS and Google Chrome only. Windows/Linux and other browsers coming soon!
- π€ AWS Bedrock LLM - Powered by Claude 3.5 Sonnet
- π Extensible - Easy to add custom LLM providers
- π Activity Classification - Automatic categorization of browser activity
- π Content-Aware - Uses page titles, URLs, and content for accurate classification
- π― Focus State Detection - FOCUSED or DRIFTING states
- π Smart Notifications - macOS notifications when you drift from goals
- π Chrome Extension - Seamless browser activity tracking
- ποΈ Auto Log Management - Automatic cleanup of old logs
| Platform | Status | Notes |
|---|---|---|
| macOS | β Supported | Full support with native notifications |
| Windows | π§ Coming Soon | Notification system needs adaptation |
| Linux | π§ Coming Soon | Notification system needs adaptation |
| Browser | Status | Notes |
|---|---|---|
| Chrome | β Supported | Full extension support |
| Edge | π§ Coming Soon | Chromium-based, should work with minor changes |
| Firefox | π§ Coming Soon | Requires Manifest V2 version |
| Safari | π§ Coming Soon | Requires Safari extension conversion |
# 1. Clone and install
git clone https://github.com/yourusername/drift-watcher.git
cd drift-watcher
# 2. Install dependencies
pip install -r requirements.txt
# 3. Install the package
pip install --no-build-isolation --no-deps .
# 4. Run with your goal (server auto-starts!)
drift-watcher --goal "Learn Python programming"
# Press Ctrl+C to stop# 1. Install dependencies
pip install -r requirements.txt
# 2. Start the event server
drift-watcher-server
# 3. In another terminal, run the agent
drift-watcher --goal "Learn Python programming"That's it! The agent will monitor your browser activity and notify you if you drift.
Install Drift Watcher globally on your system:
# Clone the repository
git clone https://github.com/yourusername/drift-watcher.git
cd drift-watcher
# Install with pip
pip install .After installation, you can run commands from anywhere:
drift-watcher --goal "Your goal"
drift-watcher-server
drift-watcher-goal
drift-watcher-switch ollamaAll data is stored in ~/.drift-watcher/
See docs/INSTALL.md for detailed installation instructions.
For development or if you prefer not to install system-wide:
- Operating System: macOS (Monterey or later recommended)
- Browser: Google Chrome
- Python: 3.8 or higher
- AWS Account: For Bedrock access with Claude 3.5 Sonnet
Note: Windows and Linux support is planned. Other Chromium-based browsers (Edge, Brave) may work but are untested.
Notification Icons: macOS notifications will show the Terminal icon due to system limitations. Custom icons require a proper .app bundle.
For system-wide installation:
git clone https://github.com/yourusername/drift-watcher.git
cd drift-watcher
pip install -r requirements.txt
pip install --no-build-isolation --no-deps .For development:
# Clone the repository
git clone https://github.com/yourusername/drift-watcher.git
cd drift-watcher
# Install Python dependencies
pip install -r requirements.txt-
Open Google Chrome and navigate to
chrome://extensions/ -
Enable Developer mode (toggle in the top-right corner)
-
Click "Load unpacked"
-
Navigate to and select the
drift-watcher-chrome-extension/directory in this project -
The extension should now appear in your extensions list with the name "Drift Watcher"
That's it! The extension will automatically start tracking your browser activity.
If you're using AWS Bedrock (default provider), configure your AWS credentials:
# Install AWS CLI if not already installed
pip install awscli
# Configure credentials
aws configureYou'll be prompted for:
- AWS Access Key ID: Your AWS access key
- AWS Secret Access Key: Your AWS secret key
- Default region name:
us-east-1(or your preferred region) - Default output format:
json
export AWS_ACCESS_KEY_ID="your-access-key"
export AWS_SECRET_ACCESS_KEY="your-secret-key"
export AWS_DEFAULT_REGION="us-east-1"Create or edit ~/.aws/credentials:
[default]
aws_access_key_id = your-access-key
aws_secret_access_key = your-secret-keyAnd ~/.aws/config:
[default]
region = us-east-1# Test AWS credentials
aws sts get-caller-identity
# Should return your AWS account informationImportant: Ensure your AWS account has access to Amazon Bedrock and the Claude model. You may need to request model access in the AWS Bedrock console.---
# Run with a goal (server auto-starts!)
drift-watcher --goal "Learn Python programming"
# Press Ctrl+C to stop
# You'll be asked if you want to stop the server too
# Or use existing goal
drift-watcher
# Manual server control (if needed)
drift-watcher-server # Start server manually
drift-watcher --no-server # Don't auto-start serverView your focus stats in real-time at http://localhost:3333/dashboard
The dashboard shows:
- Current goal and focus state (FOCUSED/DRIFTING)
- Confidence level
- Drift count (times drifted today)
- Session time
- Relevant vs irrelevant activity breakdown
- Session history sidebar with past goals
- Dark/light theme toggle
- Auto-refreshes every 30 seconds
You should see:
π Starting event server...
β
Event server started
β
Event server already running
π‘ Press Ctrl+C to stop Drift Watcher
π§ Drift Watcher started
π Config: bedrock | Window: 30s
π€ LLM: AWS Bedrock (anthropic.claude-3-5-sonnet-20240620-v1:0)
π― Goal: Learn Python programming
What Drift Watcher Does:
- Auto-starts event server if not running
- Monitors your browser activity every 30 seconds
- Assesses if you're FOCUSED or DRIFTING based on page titles and content
- Sends macOS notifications when you drift from your goal
- Asks if you want to stop the server when you quit
# View current goal
drift-watcher-goal
# Set new goal
drift-watcher-goal --set "Build a web application"drift-watcher-goalOutput:
============================================================
Current Focus Goal
============================================================
π― Learn Python programming
State: FOCUSED
Confidence: 0.7
============================================================
Edit ~/.drift-watcher/config.json and restart the agent. See Configuration for provider options.
What Drift Watcher Does:
- Monitors your browser activity every 30 seconds
- Assesses if you're FOCUSED or DRIFTING based on page titles and content
- Sends macOS notifications when you drift from your goal
Located at ~/.drift-watcher/config.json. Created automatically on first run with Ollama defaults.
{
"llm": {
"provider": "ollama",
"model": "qwen2.5:latest",
"base_url": "http://localhost:11434"
},
"agent": {
"window_seconds": 30,
"drift_confidence_threshold": 0.7,
"log_retention_days": 7
},
"server": {
"host": "127.0.0.1",
"port": 3333
}
}| Option | Description | Default |
|---|---|---|
llm.provider |
LLM provider (ollama or bedrock) |
ollama |
agent.window_seconds |
Monitoring interval in seconds | 30 |
agent.drift_confidence_threshold |
Confidence threshold for drift alerts | 0.7 |
agent.log_retention_days |
Days to keep event logs | 7 |
server.host |
Event server host | 127.0.0.1 |
server.port |
Event server port | 3333 |
When you set a new goal:
- Old event logs are cleared
- Fresh start for the new goal
Automatic cleanup:
- Logs older than 7 days are automatically deleted
- Cleanup runs on startup and every ~50 minutes
Ollama (Local, Default)
{
"llm": {
"provider": "ollama",
"model": "qwen2.5:latest",
"base_url": "http://localhost:11434"
}
}AWS Bedrock
{
"llm": {
"provider": "bedrock",
"model_id": "anthropic.claude-3-5-sonnet-20240620-v1:0",
"region_name": "us-east-1"
}
}You can add your own LLM provider by implementing BaseLLMClient. See examples/custom_provider.py for a complete example.
from drift_watcher.llm.base import BaseLLMClient
import json
class MyLLMClient(BaseLLMClient):
def __init__(self, api_key: str, model: str = "gpt-4"):
self.api_key = api_key
self.model = model
@property
def name(self) -> str:
return f"My Provider ({self.model})"
def invoke(self, prompt: str, max_tokens: int = 200, temperature: float = 0.2) -> dict:
response = your_api_call(prompt, max_tokens, temperature)
return json.loads(response)The invoke method must return a dict with:
{
"state": "FOCUSED | DRIFTING",
"confidence": 0.85,
"reason": "Brief explanation",
"relevant_percent": 80.0,
"irrelevant_percent": 20.0
}# Main agent (auto-starts server)
drift-watcher --goal "Your goal"
drift-watcher # Use existing goal
drift-watcher --no-server # Don't auto-start server
drift-watcher --keep-server # Keep server after agent stops
drift-watcher --test-notification # Test notifications
# Server
drift-watcher-server
drift-watcher-server --host 127.0.0.1 --port 3333
# Goal management
drift-watcher-goal # View current goal
drift-watcher-goal --set "New goal" # Set new goalTo switch providers, edit ~/.drift-watcher/config.json and restart.
graph LR
Browser[Chrome Browser] -->|events| Extension[Extension]
Extension -->|POST| Server[Event Server :3333]
Server -->|writes| Log[(events.log)]
Agent[Drift Watcher] -->|reads| Log
Agent -->|classifies| LLM[LLM Provider]
Agent -->|if drifting| Notify[macOS Notification]
style Browser fill:#fff4e1
style Server fill:#e8f5e9
style Agent fill:#f3e5f5
style LLM fill:#fff3e0
# Test if notifications work
drift-watcher --test-notificationNotifications not appearing
macOS Notification Settings:
- System Settings β Notifications β Terminal
- Enable "Allow Notifications"
- Set alert style to "Banners" or "Alerts"
- Disable "Do Not Disturb" mode
Check Cooldown:
- Default cooldown: 5 minutes between notifications
- Check agent output for:
π Notification cooldown: Xs remaining
Check Threshold:
- Default threshold: 0.7 confidence
- Check agent output for:
β οΈ Drifting but confidence too low - Lower threshold in
config.jsonif needed
About Notification Icons:
- macOS notifications will show the Terminal icon (system limitation)
- Custom icons require a proper .app bundle with Info.plist
- This is a macOS security feature that can't be bypassed from Python scripts
Note: Notifications currently only work on macOS. Windows/Linux support coming soon.
See TROUBLESHOOTING.md for detailed help.
Drift Watcher not detecting activity
- Verify Chrome extension is installed and enabled at
chrome://extensions/ - Check event server is running:
curl http://localhost:3333/health - Check browser console for errors (F12 β Console)
AWS Bedrock errors
- Verify AWS credentials:
aws sts get-caller-identity - Check Bedrock model access in AWS Console
- Ensure correct region in
config.json - Verify IAM permissions for Bedrock
No notifications appearing
- macOS: Grant notification permissions to Terminal/iTerm
- System Preferences β Notifications β Terminal β Allow
- Check drift confidence threshold (default: 0.7)
- Verify notifier cooldown period (default: 5 minutes)
Ollama connection errors
- Ensure Ollama is running:
ollama serve - Verify model is pulled:
ollama pull llama3.2 - Check base URL in config:
http://localhost:11434
Contributions are welcome! Here are some ways you can contribute:
- π Report bugs and issues
- π‘ Suggest new features
- π Improve documentation
- π§ Submit pull requests
- π₯οΈ Help port to Windows/Linux
- π Help create Firefox/Edge extensions
We're especially looking for help with:
-
Windows Support
- Adapt notification system for Windows 10/11
- Test and fix any platform-specific issues
-
Linux Support
- Implement notifications for various Linux desktop environments
- Test on Ubuntu, Fedora, Arch, etc.
-
Browser Extensions
- Port Chrome extension to Firefox (Manifest V2)
- Test on Edge and other Chromium browsers
- Create Safari extension version
from src.llm.base import BaseLLMClient
from src.llm import LLMFactory
class MyCustomClient(BaseLLMClient):
def invoke(self, prompt, max_tokens=200, temperature=0.2):
# Your implementation
return {"response": "..."}
@property
def name(self):
return "My Custom Provider"
# Register it
LLMFactory.register_provider("custom", MyCustomClient)See examples/custom_provider.py for a complete example.
This project is licensed under the MIT License - see the LICENSE file for details.

