Deeplok
Freedom-style distraction blocking for Omarchy. Block websites and apps with instant sessions, scheduled starts, recurring weekly blocks — and an optional locked mode you can't cheat past.
Lives in your bar. Click it to start a block, build blocklists, and manage schedules.
Features
- Blocklists — named groups of websites (
youtube.com) and apps (window class, e.g.steam,discord). Ships with a starter "Distractions" list. - Instant sessions — pick lists, pick a duration (15m…12h), block now.
- Scheduled sessions — choose a date and time; the block starts on its own.
- Recurring schedules — days of the week plus a time range
(
Mon–Fri 09:00–12:00). Overnight ranges work (22:00–06:00). - Locked mode — a locked session or schedule cannot be ended, disabled, or weakened until its end time. Enforced by a root-owned helper, not just the UI: even killing the shell doesn't lift the block.
- App blocking — windows of blocked apps are closed the moment they appear, with a notification.
- Block page — visiting a blocked site lands on block.deeplok.com: which site was blocked, when the block ends, and a rotating reminder of what the hour is worth.
Install
omarchy plugin add https://github.com/sahilhuseynzade/deeplok.git --enable
Then click the bar widget → Install system helper (authenticates once via polkit). App blocking works without this step; website blocking needs it.
How it works
- The engine runs inside
omarchy-shellas a plugin service. Every 5 seconds it evaluates your sessions and schedules and reconciles the desired block set. - Websites are blocked through a marked section in
/etc/hosts(www.variants included), applied by a small root-owned helper at/usr/local/lib/deeplok/deeplok-helper. A sudoers drop-in (/etc/sudoers.d/50-deeplok) allows exactly three invocations —apply,clear,status— with no password, so scheduled blocks engage unattended (at 2 AM, with no dialog to click). - Blocked domains point at a dedicated loopback address (
127.222.0.1), where a socket-activated systemd unit answers with a redirect to the hosted block page. No process runs while nothing is blocked — systemd spawns one short-lived responder per visit. The redirect carries?site=<domain>&until=<end>so the page can show a live countdown. - While a block is active the helper also writes an
HttpAllowlistmanaged policy for Chromium-family browsers (/etc/chromium,/etc/opt/chrome,/etc/brave) listing only the blocked hostnames, so HTTPS-First mode goes straight to the block page instead of showing a "site doesn't support a secure connection" warning. Removed when the block ends. - Apps are matched against Wayland toplevel app ids (exact, or substring of 3+ chars) and politely closed via the compositor.
- Locked mode writes a lock ledger to
/etc/deeplok/lock.json. While any entry is unexpired the helper refusesclear, refuses uninstall, and re-merges the locked domains into everyapply— so editing state files or restarting the shell won't lift the block. - State lives in
~/.config/omarchy/deeplok/state.json.
Honest limitations
- You have root on your own machine; a determined future-you can always
edit
/etc/hostswithsudo. Deeplok raises the friction (like Freedom does), it doesn't make bypass impossible. - HSTS sites still show a browser error. Sites on the HSTS preload
list (YouTube, Instagram, X, …) force
https, and no local tool can present a valid certificate for someone else's domain — so those visits show the browser's own error page instead of the block page. Sites that fall back to plainhttpget the nice page. - Privacy: the redirect sends the blocked domain and the block's end
time to
block.deeplok.comas URL parameters. The page is static; no other data leaves your machine. If you'd rather not, the blocking works identically with the redirect socket disabled. - Browsers with DNS-over-HTTPS enabled bypass
/etc/hosts. Disable DoH in the browser (or point it at the system resolver) for reliable blocking. - Browsers cache DNS; an already-open tab may keep working for a bit.
The helper flushes
systemd-resolvedon every change. - If the shell isn't running when a block should end (e.g. you're logged
out), the hosts entries stay until the shell next reconciles. Escape
hatch after a lock expires:
sudo /usr/local/lib/deeplok/deeplok-helper clear.
Uninstall
Panel → Uninstall system helper (refused while a locked block is running), then:
omarchy plugin remove shl.deeplok
Development
node --test tests/ # pure-logic tests (lib/Model.js)
omarchy plugin validate . # manifest checks
Layout: Service.qml (engine: timers, disk, processes), Panel.qml +
BarWidget.qml (UI), lib/Model.js (pure, tested logic),
bin/deeplok-helper (root side), bin/deeplok-setup (pkexec
install/uninstall), redirect/deeplok-redirect (socket-activated 302
responder), site/public/index.html (the hosted block page).