A standalone web-based monitoring interface for beads that provides real-time issue tracking through a clean, responsive web UI.
The Monitor WebUI is a separate runtime that connects to the beads daemon via RPC to provide:
- Real-time updates via WebSocket connections
- Responsive design with desktop table view and mobile card view
- Issue filtering by status and priority
- Statistics dashboard showing issue counts by status
- Detailed issue views with full metadata
- Clean, modern UI styled with Milligram CSS
The Monitor WebUI demonstrates how to build custom interfaces on top of beads using:
- RPC Protocol: Connects to the daemon's Unix socket for database operations
- WebSocket Broadcasting: Polls mutation events and broadcasts to connected clients
- Embedded Web Assets: HTML, CSS, and JavaScript served from the binary
- Standalone Binary: Runs independently from the
bdCLI
Before running the monitor, you must have:
- A beads database initialized (run
bd initin your project) - The beads daemon running (run
bd daemon)
From this directory:
go buildOr using bun (if available):
bun run go buildThis creates a monitor-webui binary in the current directory.
Start the monitor on default port 8080:
./monitor-webuiThen open your browser to http://localhost:8080
Start on a different port:
./monitor-webui -port 3000To access from other machines on your network:
./monitor-webui -host 0.0.0.0 -port 8080If your database is not in the current directory:
./monitor-webui -db /path/to/your/beads.dbIf you need to specify a custom daemon socket:
./monitor-webui -socket /path/to/beads.db.sock-port- Port for web server (default: 8080)-host- Host to bind to (default: "localhost")-db- Path to beads database (optional, will auto-detect)-socket- Path to daemon socket (optional, will auto-detect)
The monitor exposes several HTTP endpoints:
GET /- Main HTML interfaceGET /static/*- Static assets (CSS, JavaScript)
GET /api/issues- List all issues as JSONGET /api/issues/:id- Get specific issue detailsGET /api/ready- Get ready work (no blockers)GET /api/stats- Get issue statistics
WS /ws- WebSocket endpoint for real-time updates
The monitor polls the daemon every 2 seconds for mutation events and broadcasts them to all connected WebSocket clients. This provides instant updates when issues are created, modified, or closed.
- Desktop: Full table view with sortable columns
- Mobile: Card-based view optimized for small screens
- Tablet: Adapts to medium screen sizes
- Status Filter: Multi-select for Open, In Progress, and Closed
- Priority Filter: Single-select for P1, P2, P3, or All
Real-time statistics showing:
- Total issues
- In-progress issues
- Open issues
- Closed issues
monitor-webui/
├── main.go # Main application with HTTP server and RPC client
├── go.mod # Go module dependencies
├── go.sum # (generated) Dependency checksums
├── README.md # This file
└── web/ # Web assets (embedded in binary)
├── index.html # Main HTML page
└── static/
├── css/
│ └── styles.css # Custom styles
└── js/
└── app.js # JavaScript application logic
The HTML, CSS, and JavaScript files are embedded into the binary using Go's embed package. After making changes to files in the web/ directory, rebuild the binary to see your changes.
To add new API endpoints:
- Define a new handler function in
main.go - Register it with
http.HandleFunc()in themain()function - Use
daemonClientto make RPC calls to the daemon - Return JSON responses using
json.NewEncoder(w).Encode()
You can run the monitor as a systemd service. Example service file:
[Unit]
Description=Beads Monitor WebUI
After=network.target
[Service]
Type=simple
User=youruser
WorkingDirectory=/path/to/your/project
ExecStart=/path/to/monitor-webui -host 0.0.0.0 -port 8080
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.targetSave as /etc/systemd/system/beads-monitor.service and enable:
sudo systemctl enable beads-monitor
sudo systemctl start beads-monitorExample nginx configuration:
server {
listen 80;
server_name monitor.example.com;
location / {
proxy_pass http://localhost:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}Make sure you've initialized a beads database with bd init or specify the database path with -db.
The monitor requires the daemon to avoid SQLite locking conflicts. Start the daemon first:
bd daemonCheck if there's a reverse proxy or firewall between the client and server that might be closing idle connections. Consider adjusting timeout settings.
If port 8080 is already in use, specify a different port:
./monitor-webui -port 3001When deploying to production:
- Restrict Origins: Update the
CheckOriginfunction inmain.goto validate WebSocket origins - Use HTTPS: Deploy behind a reverse proxy with TLS (nginx, Caddy, etc.)
- Authentication: Add authentication middleware if exposing publicly
- Firewall: Use firewall rules to restrict access to trusted networks
The current implementation:
- Allows WebSocket connections from any origin
- Provides read-only access to issue data
- Does not include authentication
- Connects to local daemon socket only
This is appropriate for local development but requires additional security measures for production use.
Same as the main beads project.