chrono is a terminal UI (TUI) productivity tool inspired by Faceless Void’s ultimate from Dota 2 — you stop time and LOCK your targets inside the sphere.
It combines task/goal management, a configurable focus timer (simple or Pomodoro), and real-time distraction blocking (apps + websites) into a single keyboard-friendly terminal app
Where does the name come from? Faceless Void Chronosphere.
Faceless Void Chronosphere — Dota 2
- **Launch** chrono (see Usage below)
- **Start a session** from the main menu — a wizard asks one question at a time: mode, duration, task, then block targets
- **Block distractions** — the block step has four tabs (apps / domains / keywords / favorites,
Alt+1-3+Alt+F): fuzzy-add apps, type domains and keywords, or load a saved favorite profile - **Focus** — the timer counts down; blocked apps are killed every 3s; sites are blocked via /etc/hosts
- **Review** — session history is logged automatically, viewable from the
Historyscreen
Every list in chrono uses vim-style keys for navigation and selection
(block-target tabs, ban list, task list, profile list). Rows are selected
with space (single) or v (range); selected rows are highlighted.
| Key | Action |
|---|---|
j / k | Move cursor down / up |
J / K | Jump focus to the ban list / back to the picker list |
space | Toggle mark (select) the row under the cursor |
v | Toggle a visual range selection (anchor → cursor) |
d | Cut (delete) the selected rows (dd cuts the current row) |
y | Yank (copy) the selected rows (yy yanks the current row) |
p / P | Paste the clipboard after / before the cursor |
u | Undo the last cut/paste/edit |
f / F | (ban list) Add / remove the row(s) from Favorites |
gi | (block targets) Focus the current tab’s input field |
esc | Clear the selection, then blur / go back |
Read-only lists (task picker, favorites tab, profile list) only support
navigation and selection — d / y / p / P / u are disabled there.
- **Wizard Setup** — New sessions are built one question at a time (mode → duration → task → block targets → confirm), with inline fuzzy-find for tasks and block targets; typing a new task name + Enter creates it on the spot
- **Task Management** — Add, rename, delete, and complete tasks
- **Focus Timer** — Simple countdown or Pomodoro (15/5 min default), with pause/abort
- **App Blocking** — Pick installed apps by fuzzy search; processes are killed every 3s during the session
- **Website Blocking** — Block domains via /etc/hosts (sudo prompt at session start); keywords via iptables string-match on Linux (IPv4+IPv6, forces HTTP/3 back to TCP)
- **Favorite Profiles** — Save combinations of blocked apps/sites/keywords and fuzzy-pick them later
- **Session History** — Every session logged to
sessions.jsonlfor later review - **Command Palette** —
Ctrl+Pto fuzzy-navigate (Main Menu, Block Targets, Tasks, History, Settings, Quit) - **Cross-platform seam** — OS-specific facts isolated in
utils/platform.py; macOS/Windows backends planned - **One-Shot Mode** —
chrono --one-shot/chrono run <profile>starts a headless session from the CLI and exits; ban targets from a saved profile, CLI flags, or a ban file (all merged)
| Component | Library/Tool | Purpose |
|---|---|---|
| Language | Python 3.11+ | Runtime |
| TUI | textual | Terminal UI framework |
| Process mgt | psutil | Poll & kill distraction apps |
| Config | toml | Human-readable config files |
| Storage | JSON / JSONL | Tasks & session logs |
**Using uv (recommended — works on Arch Linux):**
git clone <the-repo-url> chrono
cd chrono
uv sync**Using pip (if your system pip works):**
git clone <the-repo-url> chrono
cd chrono
pip install -e .**Start the TUI (uv install — Arch Linux):**
uv run chrono tui**Or use the wrapper script (passes any args through, e.g. tui or --one-shot):**
./run.sh # TUI (bare = ./run.sh tui)
./run.sh --one-shot --apps vim --duration 25m
./run.sh run deep-work**Start the TUI (pip install):**
chrono tui**Start the TUI (without install):**
python -m chrono tui**One-shot mode:**
One-shot runs a single focus session headless and exits when it completes
(Ctrl-C aborts and logs it as aborted). There are two entry points:
chrono --one-shot [OPTIONS]
chrono run PROFILE [OPTIONS] # shorthand for --one-shot --profile PROFILEPassing any ban target flag (--profile, --apps, --websites, --keywords,
or --file) without --one-shot also enters one-shot mode, e.g.
chrono --apps vim means chrono --one-shot --apps vim. Run bare chrono
or chrono tui for the interactive TUI instead.
| Option | Meaning |
|---|---|
--profile NAME | Load the block list, mode, duration, and task from a saved profile (not available under run — pass the name positionally) |
--apps "a,b,c" | Comma-separated app names to block (matched against process names / executable basenames, case-insensitive) |
--websites "a.com,b.org" | Comma-separated domains to block (via /etc/hosts) |
--keywords "k,l" | Comma-separated keywords to block (via iptables string-match) |
--file PATH | Ban file with one kind: value entry per line (see below) |
--mode MODE | Session mode: simple or pomodoro (defaults to config/profile) |
--duration DUR | Focus duration, e.g. 25m, 1h, 90 (minutes), 30s |
--task NAME | Task name recorded for the session |
Block targets from the profile, the flags, and the ban file are all merged
(deduped, order preserved); at least one source is required. For
mode/duration/task the precedence is flag > profile > config default.
One-shot pomodoro runs one full cycle (work + break) before exiting.
Website/keyword blocking needs non-interactive sudo (or running as root);
otherwise it degrades to app blocking with a warning. Exit codes: 0
= completed, 130 = aborted, 1 = error (unknown profile / bad ban file /
nothing to block).
Examples:
chrono --one-shot --profile deep-work
chrono run deep-work # shorthand for the above
chrono --one-shot --apps vim --websites youtube.com --keywords news --duration 25m
chrono --one-shot --file ban.txt --task study
chrono --one-shot --profile deep --apps vim --file extra.txt --mode simple --task hackA ban file lists one target per line with a kind prefix (app, website, or
keyword; # lines and blanks are ignored):
app: firefox
website: reddit.com
keyword: news**Command palette (any screen):**
Ctrl+P and start typing — fuzzy match to jump to any screen.
| What | Path |
|---|---|
| Config | ~/.config/chrono/config.toml |
| Tasks | ~/.local/share/chrono/tasks.json |
| Session logs | ~/.local/share/chrono/sessions.jsonl |
| Debug logs | ~/magnus/chrono/logs/ |
