A local productivity tool that blocks distracting sites while Claude Code is idle.
Lock X combines Claude Code hooks, a local Bun server, and a Chrome extension:
- Claude Code hooks report per-instance status (
working/idle) to the local server. - The server computes aggregate state across instances.
- The extension polls that state and blocks configured sites when appropriate.
Blocking rule:
- If any Claude instance is idle, configured distracting sites are blocked.
- If all tracked instances are working (or none are running), sites are allowed.
- Temporary override can force
workingfor a short break.
- Linux with systemd user services
- Chrome/Chromium (Manifest V3 extension)
Not currently supported:
- macOS launchd setup
- Windows services
- Firefox extension packaging
- Local-only by design. No telemetry or external analytics.
- Server listens on
localhostonly. - Extension uses strict fail-closed behavior on configured blocked domains when status is uncertain.
- State is kept in-memory on the server; extension stores last known status and blocked site list in local browser storage.
git clone https://github.com/ChrisKalahiki/lock-x.git
cd lock-x
./install.shInstaller actions:
- Installs Bun dependencies
- Merges Claude hooks into
~/.claude/settings.json(idempotent) - Installs/restarts
lock-x.servicein user systemd - Prints extension setup and verification commands
- Open
chrome://extensions/ - Enable Developer mode
- Click Load unpacked
- Select
extension/
GET /health-> service metadataGET /status-> aggregate status and instance snapshotGET /config-> blocked sitesPOST /working?instance=ID-> mark instance workingPOST /idle?instance=ID-> mark instance idlePOST /override?minutes=N-> temporary break overridePOST /clear-override-> clear override
curl -s localhost:51736/health
curl -s localhost:51736/status
curl -X POST "localhost:51736/working?instance=$PPID"
curl -X POST "localhost:51736/override?minutes=10"Edit config.json:
{
"blockedSites": [
"x.com",
"twitter.com",
"reddit.com"
]
}Site matching includes root and subdomains (www, m, mobile, etc.).
bun run dev # debug server logs
bun run start # normal server
bun test # run test suite| Symptom | Check | Fix |
|---|---|---|
Extension shows ? badge |
curl -s localhost:51736/health |
Restart service: systemctl --user restart lock-x |
| Sites not blocking when expected | curl -s localhost:51736/status |
Confirm at least one instance is idle; restart extension |
| Override fails | curl -s localhost:51736/status |
Wait for cooldown (retryAfterSeconds) then retry |
| Hooks not updating status | inspect ~/.claude/settings.json |
Re-run ./install.sh and restart Claude Code |
| Service fails on boot | systemctl --user status lock-x |
Check Bun path and service environment |
./uninstall.shThen remove the extension from chrome://extensions/.
See CONTRIBUTING.md.
MIT