Introduction
tmkpr is a fast, offline-first time tracking suite written in Rust. It tracks time against projects and tasks, stores everything locally in SQLite, and gives you three interfaces to work with the same data:
| Tool | Best for |
|---|---|
tmkpr (CLI) | Scripting, automation, cron jobs, keyboard-driven workflows, SSH sessions |
tmkpr-ui | Interactive, real-time session management with a terminal dashboard |
tmkpr-pomodoro | Structured, focused work in 25/5 minute cycles with automatic logging |
All three tools share the same SQLite database, so you can start a timer in tmkpr-ui, stop it from the CLI, and see it show up in a Pomodoro session log — whichever interface fits the moment.
Key features
- Project & task management with flexible hierarchies
- Start/stop timers or manual entry logging, with natural language time input (“2 hours ago”, “yesterday 9am”)
- Retroactive editing of any entry
- Reporting — daily, weekly (ISO week), and working-week (Mon–Fri) summaries
- Tags and comments for organizing and annotating entries
- Point-in-time events for marking moments (deploys, meetings) with no duration
- CSV/JSON import and export for data portability
- Optional Obsidian integration to mirror activity into your notes vault
- 23 built-in colour themes plus custom theme support
- Offline-first — no cloud, no network dependency, full control over your data
How this manual is organized
- Installation and Quick Start get you tracking time in a few minutes.
- Configuration covers the config file, themes, and Obsidian logging — shared by all three tools.
- The CLI, terminal dashboard, and Pomodoro timer each get their own chapter with the full command/keybinding reference.
- Troubleshooting & FAQ collects common issues and fixes.
This manual documents the tools as of the
mainbranch. For a condensed version, each tool also ships its ownREADME.mdin the repository (tmkpr-cli/README.md,tmkpr-ui/README.md,tmkpr-pomodoro/README.md).
Installation
GitHub releases
Download the latest binary for your OS from the GitHub Releases page. Release binaries are built with audio support enabled for tmkpr-pomodoro. If you don’t want audio support, build from source instead.
From source
# Install all three tools (with audio)
cargo install --path tmkpr-cli
cargo install --path tmkpr-ui
cargo install --path tmkpr-pomodoro --features audio
Building
# Build all (with audio)
cargo build --release --features tmkpr-pomodoro/audio
# Build a specific tool
cargo build -p tmkpr-cli --release
cargo build -p tmkpr-ui --release
cargo build -p tmkpr-pomodoro --release --features audio
Building without audio
Linux requires libasound2-dev (Debian/Ubuntu) or alsa-lib-devel (Fedora/RHEL) to compile tmkpr-pomodoro with audio. If you’d rather skip that dependency, omit --features audio:
# Build without audio
cargo build --release
# Install without audio
cargo install --path tmkpr-pomodoro
Without the audio feature, tmkpr-pomodoro falls back to the terminal bell on phase transitions. macOS and Windows need no extra packages for audio (CoreAudio / WASAPI are used directly).
Project structure
| Crate | Role |
|---|---|
tmkpr-lib | Shared library: database, configuration, core data types |
tmkpr-cli | Command-line interface for all operations |
tmkpr-ui | Terminal dashboard UI |
tmkpr-pomodoro | Pomodoro timer with database integration |
Quick Start
1. Create a project
tmkpr project add "Client Work"
2. Add tasks to the project
tmkpr task add "Feature Development" -p "Client Work"
tmkpr task add "Bug Fixes" -p "Client Work"
3. Start tracking
# Start timing
tmkpr start -p "Client Work" -t "Feature Development"
# Do some work...
# Stop timing
tmkpr stop
# Or log directly, without a start/stop cycle
tmkpr log -s "9:00am" -e "11:30am" -p "Client Work" -t "Feature Development" -n "implemented auth flow"
4. View your work
# Today's entries
tmkpr list
# This week's report
tmkpr report --wweek
# All entries for a project
tmkpr list -p "Client Work"
5. Or use the interactive dashboard
# Launch the terminal UI
tmkpr-ui
6. Or work with Pomodoro sessions
# Launch the Pomodoro timer
tmkpr-pomodoro
All three tools read and write the same database, so you can mix and match freely — see the Configuration chapter for where that database lives and how to override it.
Configuration
Locations
- Config file:
~/.config/tmkpr/config.toml - Database:
~/.local/share/tmkpr/tmkpr.db
Override database path
Set via environment variable or command-line flag:
# Environment variable (works with all tools)
TMKPR_DB=/path/to/other.db tmkpr list
TMKPR_DB=/path/to/other.db tmkpr-ui
# Command-line flag (CLI and UI only)
tmkpr --db /path/to/other.db list
tmkpr-ui --db /path/to/other.db
When testing or experimenting, always point
--db/TMKPR_DBat a scratch file rather than your real database.
Override theme
# Environment variable
TMKPR_THEME=catppuccin_mocha tmkpr-ui
# Command-line flag
tmkpr-ui --theme dracula
See Themes for the full list and how to define your own.
Configuration file
Edit ~/.config/tmkpr/config.toml to customize settings:
[display]
time_format = "24h" # "24h" (default) or "12h"
date_format = "%Y-%m-%d %H:%M"
week_start = "mon" # mon (default), tue, wed, thu, fri, sat, sun
color = true
theme = "catppuccin_mocha" # see Themes chapter
[database]
path = "~/.local/share/tmkpr/tmkpr.db"
[pomodoro]
work_duration_minutes = 25
break_duration_minutes = 5
long_break_duration_minutes = 15
sessions_before_long_break = 4
notify_desktop = false
auto_start_break = false
Inspect the active configuration — including which file is in use and any --db override — with:
tmkpr config show
tmkpr config show --format json
Time format
In 24h mode (default), bare timestamps like 07:51 and 14:50 are accepted wherever a time is expected. In 12h mode, use 9:30am / 2:50pm style:
[display]
time_format = "24h" # "24h" or "12h"
Pomodoro settings
The [pomodoro] section configures tmkpr-pomodoro’s timer durations and notifications — see Pomodoro Configuration for the full reference.
Further reading
Themes
tmkpr-ui and tmkpr-pomodoro ship 23 built-in colour themes:
default, ayu_dark, catppuccin_frappe, catppuccin_latte, catppuccin_macchiato, catppuccin_mocha, cobalt, dracula, everforest, github_dark, github_light, gruvbox_dark, gruvbox_light, high_contrast, kanagawa, matrix, monokai, nord, onedark, rose_pine, solarized_dark, solarized_light, tokyonight
Select a theme via --theme <name>, the TMKPR_THEME environment variable, or the theme key in config.toml. In the TUI you can also type :theme <name> and use Tab to cycle through themes with a live preview — run :config-write to persist the choice.
Custom themes
Define your own theme in config.toml using hex colour values:
[themes.my_theme]
bg = "#1e1e2e"
fg = "" # leave empty for dark themes (uses terminal default); set a hex colour for light themes
active = "#a6e3a1"
accent = "#cba6f7"
dim = "#7f849c"
error = "#f38ba8"
warning = "#f9e2af"
selection = "#313244"
border = "#45475a"
For light themes, set fg to a dark hex colour so text is readable against the light background:
[themes.my_light]
bg = "#ffffff"
fg = "#1f2328" # dark text for light background
active = "#0969da"
accent = "#8250df"
dim = "#656d76"
error = "#cf222e"
warning = "#9a6700"
selection = "#ddf4ff"
border = "#d0d7de"
Then set theme = "my_theme" under [display].
Obsidian Integration
Automatically log your time tracking activities to your Obsidian vault. This feature is entirely optional and works with all three tools: CLI, TUI, and Pomodoro timer.
Setup
- Edit
~/.config/tmkpr/config.tomland add the[obsidian]section:
[obsidian]
enabled = true
vault_dir = "/path/to/your/obsidian/vault"
activity_category = "work" # optional: category for time entries
comment_category = "notes" # optional: category for comments
- Create the vault directory if it doesn’t exist and add an
obsidian-logging.yamlconfig to your vault (see the obsidian-logging documentation for details).
What gets logged
| Event | Format | Example |
|---|---|---|
| Activity Started | [STARTED] project / task (duration) | [STARTED] Backend / Feature Dev (active) |
| Activity Stopped | [STOPPED] project / task (duration) | [STOPPED] Backend / Bug Fixes (2h 30m) |
| Activity Edited | [EDITED] project / task (duration) | [EDITED] Frontend / Review (1h 15m) |
| Activity Merged | [MERGED] project / task (duration) | [MERGED] Backend / Testing (45m) |
| Activity Deleted | [DELETED] project / task (duration) | [DELETED] Support / Call (30m) |
| Comment Added | Comment entry | Comment: Fixed the bug |
| Project Created | [CREATED] project_name | [CREATED] Backend API |
| Project Updated | [UPDATED] project_name | [UPDATED] Backend API |
| Project Deleted | [DELETED] project_name | [DELETED] Archived Project |
| Task Created | [CREATED] project / task | [CREATED] Backend / Feature Dev |
| Task Updated | [UPDATED] project / task | [UPDATED] Backend / Feature Dev |
| Task Completed | [COMPLETED] project / task | [COMPLETED] Backend / Bug Fixes |
| Task Deleted | [DELETED] project / task | [DELETED] Support / Call |
Action types
Activities use these action prefixes:
[STARTED]— activity started (active timer)[STOPPED]— activity stopped (completed with duration)[EDITED]— activity edited (retroactive logging or reactivation)[COMPLETED]— activity marked complete[MERGED]— multiple activities merged into one[DELETED]— activity deleted
Tasks and projects use similar action types:
[CREATED]— new task or project created[UPDATED]— task or project name/description changed[COMPLETED]— task marked complete[DELETED]— task or project deleted
Categories
- If
activity_categoryis not specified, activities are logged to your vault’s default section. - If
comment_categoryis not specified, comments are logged to your vault’s default section. - Project and task operations are always logged to the default section.
Behavior
- Logging is completely optional — disable by setting
enabled = falseor omitting the[obsidian]section entirely. - If the vault directory doesn’t exist, logging silently fails with no error messages.
- All logging is non-blocking and doesn’t affect performance.
- Works with all three tools: CLI, TUI, and Pomodoro timer.
- Activity logs include project and task names when available.
Command-Line Interface (tmkpr)
tmkpr is the full-featured command-line interface for tmkpr time tracking. Use it for scripting, automation, integration with other tools, and fast keyboard-driven workflows.
When to use tmkpr
- Scripting & automation — pipe commands, integrate with cron jobs, git hooks, etc.
- Keyboard workflow — quick commands without GUI overhead
- Data export — JSON, CSV, Markdown output formats
- Structured queries — precise filtering and reporting
- CI/CD integration — programmatic time logging
- Remote access — works over SSH without X11
Quick start
tmkpr project add myproject
tmkpr task add coding -p myproject
tmkpr start -p myproject -t coding -n "working on feature X"
tmkpr status
tmkpr stop
tmkpr list
tmkpr report
The rest of this chapter covers each command group in detail:
- Tracking Time —
start,stop,status,log - Entries —
list,report,edit,delete,merge,fill-gap - Projects & Tasks
- Tags
- Comments
- Events
- Import & Export
- Output Formats
- Shell Completion
- Launching Other Tools
Entry and comment IDs can be abbreviated to any unambiguous prefix (8+ characters) anywhere an ID is expected.
Tracking Time
tmkpr start [-p PROJECT] [-t TASK] [-n NOTE] [-s TIME] [-f] [--tags t1,t2]
tmkpr stop [-e TIME]
tmkpr status
tmkpr log [-s START] [-e END | -d DURATION] [-p PROJECT] [-t TASK] [-n NOTE] [--tags t1,t2]
log (alias: record) adds a completed entry directly without a start/stop cycle. --end defaults to now if omitted. Use --duration instead of --end to specify how long the entry lasted (1h30m, 90m, 1:30:00); --end and --duration are mutually exclusive. If --start is omitted, tmkpr prompts with the end time of the last entry logged today; if there is no such entry, you must provide --start explicitly.
Pass --start continue (or --start cont) to start exactly where the last entry ended, with no prompt.
Handing off between tasks
If a session is already running when you run start, you will be prompted to stop it first. When --start is provided, the active entry is stopped at that time and the new entry starts at the same time — so there is no gap and no overlap:
tmkpr start -p projectB -n "context switch" --start "30 minutes ago"
# active entry stopped 30 min ago; new entry started 30 min ago
Use -f / --force to skip the confirmation prompt. It is an error to pass a --start time earlier than the active entry’s start time.
Natural language time
All time flags accept natural language or ISO 8601:
tmkpr start -p myproject --start "2 hours ago"
tmkpr stop --end "5 minutes ago"
tmkpr log -s "yesterday 9am" -e "yesterday 5pm" -p myproject -n "deep work"
tmkpr log -s "9am" -d 2h -p myproject -n "morning session"
Entries
tmkpr list [--from TIME] [--until TIME] [-p PROJECT] [-t TASK] [-l LIMIT] [--tag TAG] [--gaps] [--min-gap MINUTES]
tmkpr report [--from TIME] [--until TIME] [-p PROJECT] [--tag TAG]
tmkpr report --week [N] [--year YEAR] [--tag TAG]
tmkpr report --wweek [N] [--year YEAR] [--tag TAG]
tmkpr edit <ID> [-p PROJECT] [-t TASK] [-n NOTE] [--start TIME] [--end TIME] [--tags t1,t2 | --add-tag TAG --remove-tag TAG]
tmkpr delete <ID> [-y]
tmkpr merge <ID> [--prev]
tmkpr fill-gap [ID]
Reports
--week shows a full 7-day ISO week (Mon–Sun). --wweek shows only Mon–Fri. Both accept an optional week number and a --year flag:
tmkpr report --week # current full week
tmkpr report --wweek # current working week (Mon–Fri)
tmkpr report --wweek 12 # working week 12 of the current year
tmkpr report --week 12 --year 2025
Listing
list with no --from/--until shows today’s entries only. Pass --from to widen the range:
tmkpr list --from "last monday"
tmkpr list --from "2025-01-01"
Merging and gap filling
merge (alias: m) joins an entry into the chronologically next entry that shares its project and task. Pass --prev to merge into the previous entry instead.
fill-gap (alias: fg) extends an entry’s start and/or end times to abut adjacent entries on the same day. Omit ID to operate on the active entry.
Editing
Entry IDs can be abbreviated to any unambiguous prefix (8+ chars).
edit --tags replaces all tags on an entry. To add or remove individual tags without specifying the full set, use --add-tag and --remove-tag (each can be given multiple times; both conflict with --tags):
tmkpr edit abc12345 --add-tag billable
tmkpr edit abc12345 --remove-tag wip --add-tag done
Projects & Tasks
Projects
tmkpr project add <NAME> [-d DESCRIPTION] [--color HEX]
tmkpr project list [--archived]
tmkpr project edit <NAME|ID> [--name NAME] [-d DESCRIPTION] [--color HEX]
tmkpr project delete <NAME|ID> [--hard]
Projects are listed with a numeric ID. Both the name and numeric ID are accepted wherever NAME|ID appears.
Deleting a project archives it by default. Use --hard to permanently remove it. Pass - to --description or --color to clear those fields.
Tasks
tmkpr task add <NAME> -p PROJECT [-d DESCRIPTION]
tmkpr task list -p PROJECT [--archived]
tmkpr task edit <NAME|ID> -p PROJECT [--name NAME] [-d DESCRIPTION] [--move-to PROJECT]
tmkpr task delete <NAME|ID> -p PROJECT [--hard]
tmkpr task done <NAME|ID> -p PROJECT
tmkpr task reactivate <NAME|ID> -p PROJECT
-p identifies the project the task currently belongs to. Use --move-to to reassign it to a different project.
task delete archives by default; use --hard to permanently remove. task done marks a task completed; task reactivate reverses that.
Tags
tmkpr tag list
Lists all tags in use across entries, with entry counts. Accepts --format like any other list command (see Output Formats).
Tags are attached to entries at creation (start --tags, log --tags, event add --tags) or updated afterward with edit --tags / --add-tag / --remove-tag (see Entries). Filter entries or reports by tag with --tag TAG on list, report, and event list.
Comments
Add free-form notes to any entry.
tmkpr comment add [-e ENTRY-ID] <TEXT...>
tmkpr comment list # comments on active entry
tmkpr comment list <ENTRY-ID> # comments on a specific entry
tmkpr comment edit <ID> <TEXT...>
tmkpr comment delete <ID> [-y]
comment add targets the active entry by default; use -e to add to any finished entry:
tmkpr comment add just deployed the fix
tmkpr comment add -e abc12345 actually deployed to staging
Aliases: c for the subcommand, a / ls / e / d for the actions. Comment IDs can be abbreviated to any unambiguous prefix (8+ chars).
Events
Point-in-time events are entries with no duration — useful for marking moments (deploys, meetings, etc.).
tmkpr event add [--at TIME] [-p PROJECT] [-t TASK] [-n NOTE] [--tags t1,t2]
tmkpr event list [--from TIME] [--until TIME] [-p PROJECT] [--tag TAG] [-l LIMIT]
tmkpr event edit <ID> [--at TIME] [-p PROJECT] [-t TASK] [-n NOTE] [--tags t1,t2]
tmkpr event delete <ID> [-y]
--at accepts natural language or ISO 8601 and defaults to now. Events also appear in tmkpr list alongside regular entries.
Import & Export
tmkpr import [FILE] [--skip-errors] [--dry-run]
tmkpr export [FILE] [-p PROJECT] [-t TASK] [--from TIME] [--until TIME] [--tag TAG] [--no-active]
Import
Reads projects, tasks, and time entries from a CSV or JSON file and creates any missing projects and tasks automatically.
Supported CSV columns (case-insensitive, spaces/hyphens treated as underscores):
| Column | Notes |
|---|---|
start | Combined start datetime (required — or split into start_date + start_time) |
start_date, start_time | Alternative split form |
end / end_date / end_time | End datetime; omit for an active entry |
duration | Duration instead of end time (1:30:00, 1h30m, 90m) |
project | Project name — created if it doesn’t exist |
task | Task name within the project — created if it doesn’t exist |
note / description / comment | Free-text note |
tags | Comma-separated tags |
tmkpr import entries.csv # import from file
tmkpr import entries.json # JSON file (auto-detected by extension)
tmkpr import --dry-run entries.csv # preview without writing
tmkpr import --skip-errors entries.csv # continue past bad rows
tmkpr import - # read CSV from stdin
tmkpr -f json import - # read JSON from stdin
Export
Writes entries to CSV (default) or JSON. Columns: project, task, start, end, note, tags. Datetimes are written in local time so files round-trip cleanly through import.
tmkpr export # all entries to stdout (CSV)
tmkpr export entries.csv # all entries to file
tmkpr export entries.json # JSON (auto-detected by extension)
tmkpr -f json export # JSON to stdout
tmkpr export --from 2024-01-01 out.csv # date range
tmkpr export -p "My Project" out.csv # filter by project
tmkpr export | tmkpr import - # round-trip: export then re-import
Output Formats
All list-producing commands accept --format table (default), --format json, --format csv, or --format markdown.
tmkpr list --format json
tmkpr list --format markdown
tmkpr report --format csv
tmkpr report --format markdown
tmkpr project list --format json
tmkpr task list -p myproject --format csv
project list --format json includes a tasks array on each project object, making it suitable for scripting:
tmkpr project list --format json \
| jq -r '.[] | . as $p | .tasks[] | "\($p.name) / \(.name)"'
CSV output uses raw seconds for duration fields to keep it machine-readable.
See Configuration for the time_format setting that controls how times are displayed in table output.
Shell Completion
Dynamic completion (recommended)
Includes project and task name suggestions:
# bash — add to ~/.bashrc
source <(COMPLETE=bash tmkpr)
# zsh — add to ~/.zshrc
source <(COMPLETE=zsh tmkpr)
# fish — add to ~/.config/fish/completions/tmkpr.fish
COMPLETE=fish tmkpr | source
Static completion
Flags and subcommands only, no dynamic project/task lookups:
tmkpr completion bash >> ~/.bashrc
tmkpr completion zsh >> ~/.zshrc
tmkpr completion fish > ~/.config/fish/completions/tmkpr.fish
Launching Other Tools
tmkpr ui and tmkpr pomodoro launch the sibling terminal apps without you needing to remember their binary names. All flags are forwarded, including --db:
tmkpr ui # launch tmkpr-ui
tmkpr u # alias
tmkpr ui --theme dracula # pass flags through
tmkpr pomodoro # launch tmkpr-pomodoro
tmkpr pomo # alias
tmkpr p25 # alias
tmkpr --db /path/to/other.db ui # --db is forwarded automatically
tmkpr --db /path/to/other.db pomodoro
Terminal Dashboard (tmkpr-ui)
Interactive terminal dashboard for tmkpr time tracking, built with ratatui. Perfect for real-time visibility, interactive session management, and an intuitive keyboard-driven workflow.
When to use tmkpr-ui
- Interactive tracking — start/stop timers with visual feedback
- Quick overview — see active timers, week totals, and recent entries at a glance
- Real-time management — pause, resume, edit, and delete entries on the fly
- Visual organization — manage projects and tasks interactively
- Desktop workflow — full-featured UI without leaving the terminal
Launch
tmkpr-ui
# or via the CLI
tmkpr ui
Overrides
# Database
tmkpr-ui --db /path/to/other.db
TMKPR_DB=/path/to/other.db tmkpr-ui
# Theme
tmkpr-ui --theme catppuccin_mocha
TMKPR_THEME=dracula tmkpr-ui
Layout
The dashboard shows:
- Active entry — currently running timer with elapsed time (top); includes the running task in the week total
- Entry list — the 50 most recent completed entries
- Week report — total time per day and project for the displayed ISO week (sidebar); navigate with
<and> - Status bar — feedback messages and error hints (bottom)
Continue to Layout & Keybindings for the full key reference, Command Mode for the : command bar, and Settings Dialog for the in-app settings editor.
Layout & Keybindings
Normal mode
| Key | Action |
|---|---|
j / ↓ | Select next entry |
k / ↑ | Select previous entry |
s | Start tracking (opens form) |
S | Start tracking pre-filled from selected entry |
n | Add a manual entry (opens form) |
v | Add a point-in-time event (defaults to now) |
x | Stop active entry |
e | Edit selected entry |
E | Edit active (currently running) entry |
d | Delete selected entry (prompts for confirmation) |
c | Open comments for selected entry |
C | Open comments for active entry |
m | Merge selected entry with the next one |
g | Fill time gaps around the selected entry |
G | Fill time gaps around the active entry |
f | Open filter |
T | Filter to today |
Y | Filter to yesterday |
P | Filter to previous week |
N | Filter to next week |
o | Cycle entry sort order |
< | View previous week in week report |
> | View next week in week report |
p | Manage projects |
t | Manage tasks |
r | Refresh data |
: | Enter command mode |
i | Open settings dialog |
? | Show help |
q / Esc | Quit |
Ctrl-c | Quit |
Manage projects
| Key | Action |
|---|---|
j / ↓ | Select next project |
k / ↑ | Select previous project |
a | Add a new project |
e | Edit selected project |
d | Delete selected project |
s | Cycle sort order |
f | Filter projects |
q / Esc | Return to main view |
Manage tasks
| Key | Action |
|---|---|
j / ↓ | Select next task |
k / ↑ | Select previous task |
a | Add a new task |
e | Edit selected task |
d | Delete selected task |
c | Toggle task complete / reactivate |
s | Cycle sort order |
f | Filter tasks |
q / Esc | Return to main view |
Comments panel
| Key | Action |
|---|---|
j / ↓ | Select next comment |
k / ↑ | Select previous comment |
a | Add a new comment |
e | Edit selected comment |
d | Delete selected comment |
q / Esc | Return to main view |
Forms (start, edit, filter, add project, add task)
| Key | Action |
|---|---|
Tab | Accept highlighted completion (if any), then advance to next field |
Shift-Tab | Move to previous field |
↓ | On completion fields: select next suggestion in dropdown |
↑ | On completion fields: select previous suggestion in dropdown |
Enter | Accept highlighted completion and advance field; submit on the last field |
Space | On toggle fields: flip [✓] On / [ ] Off |
Esc | Cancel |
Project and task fields show a dropdown of matching names as you type. Use ↓/↑ to highlight a suggestion, then Tab or Enter to accept it.
Manual entry form
Press n to add a past or off-session entry (only available when no timer is active).
| Field | Notes |
|---|---|
| Project | Autocompleted from existing projects; creates a new project on submit if not found |
| Task | Autocompleted from tasks in the selected project; creates a new task on submit if not found |
| Note | Free-text description |
| Start | YYYY-MM-DD HH:MM or HH:MM (today is assumed when only a time is given) |
| End | Same format as Start; leave blank to create an active (running) entry |
| Tags | Comma-separated list |
| Snap to existing activities | Toggle with Space — when on, the start and end times are snapped to the nearest boundary of an existing entry |
Filter dialogs
Accessible via f from the main view, the project list, or the task list. Each opens a small form scoped to its context:
- Entry filter — project name and date range (e.g.
today,this week,2024-06-01..2024-06-30) - Project filter — show or hide archived projects
- Task filter — filter by project, show/hide archived and completed tasks
Submit with Enter on the last field; cancel with Esc.
Help dialog
Press ? to open the help reference. The dialog is scrollable when content exceeds the visible area.
| Key | Action |
|---|---|
j / ↓ | Scroll down |
k / ↑ | Scroll up |
Page Down | Scroll down 10 lines |
Page Up | Scroll up 10 lines |
| Any other key | Close |
Delete confirmation
| Key | Action |
|---|---|
y / Enter | Confirm delete |
| Any other key | Cancel |
Command Mode
Press : to open the command bar. Use Tab / ↓ and Shift-Tab / ↑ to cycle through completions, Enter to execute, Esc to cancel.
| Command | Action |
|---|---|
theme <name> | Switch colour theme (live preview while cycling) |
set date-format <preset> | Change date display format |
set week-start <day> | Set first day of the week (e.g. mon, sun) |
config-open | Open config.toml in $EDITOR |
config-reload | Reload config from disk |
config-write | Persist current theme and display settings to config |
quit | Quit |
Theme and display changes take effect immediately but are only written to disk with :config-write.
Settings Dialog
Press i to open the interactive settings dialog. Changes are staged in the dialog and written to disk when you press s or Enter.
| Key | Action |
|---|---|
j / ↓ | Next setting |
k / ↑ | Previous setting |
← / → | Cycle value (theme, date format, week start) |
Space / ← / → | Toggle boolean (Obsidian enabled) |
Enter | On text fields: start inline editing; on other rows: save and close |
s | Save and close |
Esc | Cancel (restores any live theme preview) |
Settings covered
| Setting | Description |
|---|---|
| Theme | Cycles through all built-in and custom themes with live preview |
| Date format | YYYY-MM-DD HH:MM, DD-MM-YYYY HH:MM, or MM-DD-YYYY HH:MM |
| Week start | First day of the week shown in the sidebar report |
| Obsidian enabled | Toggle Obsidian logging on/off |
| Vault directory | Absolute path to your Obsidian vault |
| Activity category | Obsidian heading under which time entries are logged |
| Comment category | Obsidian heading under which comments are logged |
See Obsidian Integration for what these settings control.
Pomodoro Timer (tmkpr-pomodoro)
Terminal-based Pomodoro timer integrated with the tmkpr time tracking database. Manage focused work sessions with built-in breaks, automatic logging, and notifications.
When to use tmkpr-pomodoro
- Focused work sessions — structure your day with timed intervals
- Break reminders — automatic breaks to prevent burnout
- Session logging — automatically record completed Pomodoros to the database
- Notifications — audio and desktop alerts for transitions
- Distraction-free — stay in the terminal, avoid context switching
Features
- Pomodoro timer: 25-minute work sessions with 5-minute breaks (configurable)
- Long breaks: automatic longer breaks after N work sessions (default: 15 minutes after 4 sessions)
- Project & task management: select from, create, edit, and delete projects/tasks stored in your tmkpr database
- Task filtering: hide or show completed tasks with a single keypress
- Session logging: automatically log completed work sessions to the database
- Configurable notifications: audio file playback and/or system desktop notifications on transitions
- In-app settings: edit all configuration without leaving the terminal
- Session progress: visual feedback on where you are in the work/break cycle
Starting the timer
tmkpr-pomodoro
# or via the CLI
tmkpr pomodoro
tmkpr pomo # alias
tmkpr p25 # alias
# Override database
TMKPR_DB=/path/to/other.db tmkpr-pomodoro
# Override theme
tmkpr-pomodoro --theme nord
TMKPR_THEME=catppuccin_mocha tmkpr-pomodoro
UI layout
┌─ Timer ─────────────────────────────────────────────────────┐
│ 12:34 / 25:00 [RUNNING] │
│ Session 2 of 4 │
└─────────────────────────────────────────────────────────────┘
┌─ Projects ──────────────┬─ Tasks ─────────────┬─ Completed ─┐
│ ▶ Project A │ ▶ Task 1 │ #1 10:00 │
│ Project B │ Task 2 │ #2 5:45 │
│ Project C │ Task 3 ✓ │ │
└─────────────────────────┴─────────────────────┴─────────────┘
┌─ Status ────────────────────────────────────────────────────┐
│ Timer running... │
└─────────────────────────────────────────────────────────────┘
┌─ Help ──────────────────────────────────────────────────────┐
│ ↑↓: Project | ←→: Task | Enter: Work | B: Break │
│ N: New task | P: New project | E: Edit | D: Delete │
│ H: Hide completed | C: Complete | S: Settings | Q: Quit
└─────────────────────────────────────────────────────────────┘
Completed task filtering: the Tasks column title changes when filters are active — Tasks (all visible) vs. Tasks (completed hidden) (only incomplete tasks shown).
Database integration
The timer integrates with the tmkpr SQLite database:
- Reads from: projects and tasks
- Writes to: time entries (when logging sessions with the
Lkey) - Database path: configured in
~/.config/tmkpr/config.toml([database]section), or overridden with--db/TMKPR_DB
Continue to Keyboard Controls and Timer Cycle & Notifications, or jump to Configuration for the full [pomodoro] settings reference.
Keyboard Controls
Main screen
Navigation & timer
| Key | Action |
|---|---|
↑ / ↓ | Select project |
← / → | Select task |
Enter | Start work session |
B | Start break (short or long) |
Space | Pause / Resume |
L | Log current session to database |
R | Reset timer |
Project & task management
| Key | Action |
|---|---|
P | Create new project |
N | Create new task in selected project |
E | Edit selected project or task name |
D | Delete selected project or task (with confirmation) |
C | Toggle selected task complete / reactivate |
H | Hide / show completed tasks |
Other
| Key | Action |
|---|---|
S | Open settings |
Q / Esc | Quit (only when stopped) |
Creating & editing projects and tasks
When creating or editing, a text input field appears in the Projects or Tasks column:
- Type your text
- Press
Enterto save - Press
Escto cancel - Backspace works to delete characters
When editing, the field is pre-populated with the current name. Delete and recreate if you need to replace entirely.
Settings screen
| Key | Action |
|---|---|
↑ / ↓ | Navigate between settings |
← / → | Adjust value |
Enter | Save and return to main |
Esc | Cancel and discard changes |
Timer Cycle & Notifications
Timer cycle
The timer follows this pattern (with default durations):
- Work session: 25 minutes (started with
Enter) - Short break: 5 minutes
- (repeat 3 more times)
- Long break: 15 minutes
- (cycle repeats)
Example: Work → Break → Work → Break → Work → Break → Work → Long Break → (repeat)
Break transitions
When a work session completes:
- With
auto_start_break = true: break timer starts immediately and continues counting down - With
auto_start_break = false: timer pauses, allowing you to set up before pressingSpaceto resume
You can also start a break manually at any time with B (when the timer is stopped). This:
- Immediately starts a break (short or long, depending on cycle position)
- Increments the work session counter toward the next long break
- Is useful for taking breaks without doing a work session first
All durations and cycle length are configurable in settings.
Notifications
Audio
- Requires the
audiofeature flag at build time (--features audio) - Plays an audio file when sessions transition
- Configure separate files for work→break and break→work transitions
- Supports WAV, MP3, OGG Vorbis, and FLAC
- Omit the setting (or leave it empty) to disable sound for that transition
- Without the
audiofeature, the terminal bell is emitted on every transition instead
Desktop notifications
- Shows a system notification when a session ends/starts
- Requires a notification daemon (Linux) or native notification support (macOS/Windows)
- Disabled by default (opt-in with
notify_desktop = true) - Fails gracefully if the notification daemon is unavailable
Status messages
- Displayed in the Status bar when state changes
- Auto-clear after a configurable timeout (default 5 seconds)
- Set
message_timeout_secs = 0to keep messages visible
Configuration
Settings are stored in ~/.config/tmkpr/config.toml. You can edit them directly in the file or through the in-app settings screen (press S).
Configuration options
[pomodoro]
# Timer durations (in minutes)
work_duration_minutes = 25
break_duration_minutes = 5
long_break_duration_minutes = 15
# Number of work sessions before a long break
sessions_before_long_break = 4
# Notifications
notify_desktop = false # System notifications (opt-in)
message_timeout_secs = 5 # Auto-clear status messages (0 = never)
# Audio (WAV, MP3, OGG, FLAC supported; omit to disable)
sound_work_to_break = "" # Played when a work session ends
sound_break_to_work = "" # Played when a break ends
# Break behavior
auto_start_break = false # Auto-start break when work ends (true) or pause (false)
# Cycle limit (0 = unlimited)
max_cycles = 0 # Stop automatically after this many work sessions
Configuration examples
Quiet mode (no notifications):
[pomodoro]
notify_desktop = false
message_timeout_secs = 0
Audio + desktop notifications:
[pomodoro]
sound_work_to_break = "/home/user/sounds/gong.wav"
sound_break_to_work = "/home/user/sounds/bell.ogg"
notify_desktop = true
message_timeout_secs = 3
Short sessions (for testing):
[pomodoro]
work_duration_minutes = 1
break_duration_minutes = 1
long_break_duration_minutes = 2
message_timeout_secs = 2
Pause between sessions (for setup/review):
[pomodoro]
auto_start_break = false # Pause when work ends, resume manually
message_timeout_secs = 3
Continuous flow (minimal interruption):
[pomodoro]
auto_start_break = true # Breaks start automatically
message_timeout_secs = 2
Troubleshooting & FAQ
Build fails: “Package alsa was not found in the pkg-config search path”
This occurs on Linux when building tmkpr-pomodoro with --features audio and the ALSA development headers are not installed. Install them before building:
# Debian / Ubuntu
sudo apt install libasound2-dev
# Fedora / RHEL
sudo dnf install alsa-lib-devel
Alternatively, build without the audio feature — the terminal bell is used instead:
cargo build -p tmkpr-pomodoro --release
Settings not saving
- Ensure
~/.config/tmkpr/is writable. - Check for permission errors in terminal output.
Desktop notifications not showing
- On Linux: install a notification daemon (e.g.
notification-daemon,dunst). - On macOS: system notifications should work automatically.
- On Windows: requires Windows 10 or later.
Timer not advancing (tmkpr-pomodoro)
- Ensure the timer is running (should show
[RUNNING]in the timer display). - Press
Spaceto resume if paused.
Can’t open settings (tmkpr-pomodoro)
- The settings screen is only available when the timer is stopped.
- Press
Rto reset the timer first.
Where is my data stored?
- Config file:
~/.config/tmkpr/config.toml - Database:
~/.local/share/tmkpr/tmkpr.db
See Configuration for how to override either location.
I want to try tmkpr without touching my real data
Point every command at a scratch database with --db or TMKPR_DB:
TMKPR_DB=/tmp/test-tmkpr.db tmkpr project add demo
TMKPR_DB=/tmp/test-tmkpr.db tmkpr-ui
How do I check my active configuration?
tmkpr config show
tmkpr config show --format json
This prints the resolved configuration and the path to the config file in use, including any --db override.