A Chrome extension that displays an attention-grabbing overlay on distracting websites when your AI agent needs your input. Works with Claude Code, and any tool that can make HTTP requests.
- Non-blocking overlay - Sites remain fully functional; an overlay appears on top
- Real-time updates - Overlay appears/disappears instantly based on agent status
- Multi-instance support - Track multiple agent sessions simultaneously
- Configurable sites - Add or remove watched sites via the popup UI
- Configurable port - Use any port for the status server
- Generic webhook API - Integrate with any AI tool or automation
- Cross-platform - Works on macOS, Linux, and Windows
┌──────────────────────────────────────────────────────────────────┐
│ AGENT NUDGE SYSTEM │
├──────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────────┐ HTTP Poll ┌──────────────────┐ │
│ │ Chrome Extension │ ◄─────────────────► │ Status Server │ │
│ │ (Content Script) │ (every 2s) │ (localhost:9999)│ │
│ └──────────────────┘ └──────────────────┘ │
│ │ ▲ │
│ │ Injects overlay │ │
│ ▼ │ │
│ ┌──────────────────┐ ┌──────────────────┐ │
│ │ Watched Sites │ │ Any AI Agent │ │
│ │ (configurable) │ │ - Claude Code │ │
│ │ │ │ - Custom tools │ │
│ └──────────────────┘ │ - Automations │ │
│ └──────────────────┘ │
│ │
└──────────────────────────────────────────────────────────────────┘
cd server
npm installRun in foreground (for testing):
npm startRun in background:
npm run start:bg # Start in background
npm run status # Check if running
npm run logs # View logs
npm run stop # Stop serverRun as macOS service (auto-starts on login):
./install-service.sh # Install and start
./uninstall-service.sh # Remove serviceThe server runs on http://localhost:9999 by default.
- Open Chrome and navigate to
chrome://extensions - Enable "Developer mode" (toggle in top right)
- Click "Load unpacked"
- Select the
extension/folder - The Agent Nudge icon should appear in your toolbar
If using with Claude Code:
Automatic installation:
./install-hooks.shManual installation: Add the following to ~/.claude/settings.json:
{
"hooks": {
"UserPromptSubmit": [
{
"hooks": [{"type": "command", "command": "/path/to/agent-nudge/hooks/start-work.sh"}]
}
],
"PreToolUse": [
{
"hooks": [{"type": "command", "command": "/path/to/agent-nudge/hooks/start-work.sh"}]
}
],
"Stop": [
{
"hooks": [{"type": "command", "command": "/path/to/agent-nudge/hooks/stop-work.sh"}]
}
]
}
}Replace /path/to/agent-nudge with the actual path to this project.
Set a custom port using the AGENT_NUDGE_PORT environment variable:
# Start server on custom port
AGENT_NUDGE_PORT=8888 npm startOr create a .env file (copy from .env.example):
AGENT_NUDGE_PORT=8888
Update the port in the extension popup to match.
Configure which sites show the overlay via the extension popup:
- Click the Agent Nudge icon in Chrome
- Use the "Watched Sites" section to add/remove sites
- Click "Reset to Defaults" to restore the default list
Default sites:
- youtube.com
- twitter.com / x.com
- reddit.com
- facebook.com
- instagram.com
- tiktok.com
- twitch.tv
Agent Nudge works with any tool that can make HTTP requests. Use the simple webhook API to signal when your agent/tool starts and stops working.
| Endpoint | Method | Description |
|---|---|---|
/api/start |
POST | Signal agent started working |
/api/stop |
POST | Signal agent stopped (needs attention) |
/api/heartbeat |
POST | Keep session alive |
/api/status |
GET | Get current status |
/api/unregister |
POST | Remove an instance |
/health |
GET | Health check |
# Signal work started (hides overlay)
curl -X POST http://localhost:9999/api/start \
-H "Content-Type: application/json" \
-d '{"instanceId": "my-tool", "name": "My Custom Tool", "source": "my-tool"}'
# Signal work stopped (shows overlay)
curl -X POST http://localhost:9999/api/stop \
-H "Content-Type: application/json" \
-d '{"instanceId": "my-tool", "source": "my-tool"}'
# Check status
curl http://localhost:9999/api/status
# Remove instance when done
curl -X POST http://localhost:9999/api/unregister \
-H "Content-Type: application/json" \
-d '{"instanceId": "my-tool"}'import requests
BASE_URL = "http://localhost:9999"
def start_work(instance_id, name="My Agent"):
requests.post(f"{BASE_URL}/api/start", json={
"instanceId": instance_id,
"name": name,
"source": "python-agent"
})
def stop_work(instance_id):
requests.post(f"{BASE_URL}/api/stop", json={
"instanceId": instance_id,
"source": "python-agent"
})
# Usage
start_work("session-123", "Data Processing")
# ... do work ...
stop_work("session-123")const BASE_URL = 'http://localhost:9999';
async function startWork(instanceId, name = 'My Agent') {
await fetch(`${BASE_URL}/api/start`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ instanceId, name, source: 'node-agent' })
});
}
async function stopWork(instanceId) {
await fetch(`${BASE_URL}/api/stop`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ instanceId, source: 'node-agent' })
});
}For Windows users, use the .bat hook files instead of .sh:
- Configure Claude Code hooks to use the Windows batch files:
{
"hooks": {
"UserPromptSubmit": [
{
"hooks": [{"type": "command", "command": "C:\\path\\to\\agent-nudge\\hooks\\start-work.bat"}]
}
],
"PreToolUse": [
{
"hooks": [{"type": "command", "command": "C:\\path\\to\\agent-nudge\\hooks\\start-work.bat"}]
}
],
"Stop": [
{
"hooks": [{"type": "command", "command": "C:\\path\\to\\agent-nudge\\hooks\\stop-work.bat"}]
}
]
}
}- Set the port via environment variable (optional):
set AGENT_NUDGE_PORT=8888Click the extension icon to:
- Toggle the extension on/off
- Configure the server port
- See current agent status (Working/Needs Attention)
- View active instance count
- Dismiss the overlay temporarily (5, 15, or 30 minutes)
- Manage watched sites
# Check status
curl http://localhost:9999/api/status
# Simulate agent starting work (hides overlay)
curl -X POST http://localhost:9999/api/start \
-H "Content-Type: application/json" \
-d '{"source": "test"}'
# Simulate agent stopping (shows overlay)
curl -X POST http://localhost:9999/api/stop \
-H "Content-Type: application/json" \
-d '{"source": "test"}'- Start the server:
npm start - Load the extension in Chrome
- Open YouTube and start a video
- Run
curl -X POST http://localhost:9999/api/stop - The overlay should appear (video keeps playing)
- Run
curl -X POST http://localhost:9999/api/start - The overlay should disappear within 2 seconds
If no heartbeat is received for 5 minutes while an agent is marked as active, the server automatically transitions to "needs attention" state, showing the overlay.
- Check if the server is running:
curl http://localhost:9999/health - Check the extension is enabled in
chrome://extensions - Make sure the site is in your watched sites list
- Verify the port matches between server and extension
- Check the browser console for errors
- Make sure the server is running on the correct port
- Check for firewall or proxy issues
- Verify CORS is working (check browser console)
- Make sure Developer Mode is enabled in Chrome
- Check for errors in the extension card on
chrome://extensions - Try reloading the extension
agent-nudge/
├── extension/ # Chrome Extension
│ ├── manifest.json # Extension manifest (V3)
│ ├── background.js # Service worker - polls status
│ ├── content.js # Injected into sites - shows overlay
│ ├── content.css # Overlay styling
│ ├── popup.html # Extension popup UI
│ ├── popup.js # Popup logic
│ ├── popup.css # Popup styling
│ └── icons/ # Extension icons
├── server/ # Local Status Server
│ ├── package.json
│ ├── server.js # Express server
│ └── README.md
├── hooks/ # Agent integration hooks
│ ├── start-work.sh # macOS/Linux: Signal work started
│ ├── stop-work.sh # macOS/Linux: Signal work stopped
│ ├── exit.sh # macOS/Linux: Unregister on exit
│ ├── start-work.bat # Windows: Signal work started
│ ├── stop-work.bat # Windows: Signal work stopped
│ └── exit.bat # Windows: Unregister on exit
├── install-hooks.sh # Auto-install Claude hooks
├── install-service.sh # Install as macOS service
├── uninstall-service.sh # Remove macOS service
├── .env.example # Environment configuration template
├── package.json # Root package
├── LICENSE # MIT License
└── README.md # This file
MIT