Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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:

ToolBest for
tmkpr (CLI)Scripting, automation, cron jobs, keyboard-driven workflows, SSH sessions
tmkpr-uiInteractive, real-time session management with a terminal dashboard
tmkpr-pomodoroStructured, 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 main branch. For a condensed version, each tool also ships its own README.md in 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

CrateRole
tmkpr-libShared library: database, configuration, core data types
tmkpr-cliCommand-line interface for all operations
tmkpr-uiTerminal dashboard UI
tmkpr-pomodoroPomodoro 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_DB at 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

  1. Edit ~/.config/tmkpr/config.toml and 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
  1. Create the vault directory if it doesn’t exist and add an obsidian-logging.yaml config to your vault (see the obsidian-logging documentation for details).

What gets logged

EventFormatExample
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 AddedComment entryComment: 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_category is not specified, activities are logged to your vault’s default section.
  • If comment_category is 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 = false or 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:

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):

ColumnNotes
startCombined start datetime (required — or split into start_date + start_time)
start_date, start_timeAlternative split form
end / end_date / end_timeEnd datetime; omit for an active entry
durationDuration instead of end time (1:30:00, 1h30m, 90m)
projectProject name — created if it doesn’t exist
taskTask name within the project — created if it doesn’t exist
note / description / commentFree-text note
tagsComma-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

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

KeyAction
j / ↓Select next entry
k / ↑Select previous entry
sStart tracking (opens form)
SStart tracking pre-filled from selected entry
nAdd a manual entry (opens form)
vAdd a point-in-time event (defaults to now)
xStop active entry
eEdit selected entry
EEdit active (currently running) entry
dDelete selected entry (prompts for confirmation)
cOpen comments for selected entry
COpen comments for active entry
mMerge selected entry with the next one
gFill time gaps around the selected entry
GFill time gaps around the active entry
fOpen filter
TFilter to today
YFilter to yesterday
PFilter to previous week
NFilter to next week
oCycle entry sort order
<View previous week in week report
>View next week in week report
pManage projects
tManage tasks
rRefresh data
:Enter command mode
iOpen settings dialog
?Show help
q / EscQuit
Ctrl-cQuit

Manage projects

KeyAction
j / ↓Select next project
k / ↑Select previous project
aAdd a new project
eEdit selected project
dDelete selected project
sCycle sort order
fFilter projects
q / EscReturn to main view

Manage tasks

KeyAction
j / ↓Select next task
k / ↑Select previous task
aAdd a new task
eEdit selected task
dDelete selected task
cToggle task complete / reactivate
sCycle sort order
fFilter tasks
q / EscReturn to main view

Comments panel

KeyAction
j / ↓Select next comment
k / ↑Select previous comment
aAdd a new comment
eEdit selected comment
dDelete selected comment
q / EscReturn to main view

Forms (start, edit, filter, add project, add task)

KeyAction
TabAccept highlighted completion (if any), then advance to next field
Shift-TabMove to previous field
↓On completion fields: select next suggestion in dropdown
↑On completion fields: select previous suggestion in dropdown
EnterAccept highlighted completion and advance field; submit on the last field
SpaceOn toggle fields: flip [✓] On / [ ] Off
EscCancel

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).

FieldNotes
ProjectAutocompleted from existing projects; creates a new project on submit if not found
TaskAutocompleted from tasks in the selected project; creates a new task on submit if not found
NoteFree-text description
StartYYYY-MM-DD HH:MM or HH:MM (today is assumed when only a time is given)
EndSame format as Start; leave blank to create an active (running) entry
TagsComma-separated list
Snap to existing activitiesToggle 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.

KeyAction
j / ↓Scroll down
k / ↑Scroll up
Page DownScroll down 10 lines
Page UpScroll up 10 lines
Any other keyClose

Delete confirmation

KeyAction
y / EnterConfirm delete
Any other keyCancel

Command Mode

Press : to open the command bar. Use Tab / ↓ and Shift-Tab / ↑ to cycle through completions, Enter to execute, Esc to cancel.

CommandAction
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-openOpen config.toml in $EDITOR
config-reloadReload config from disk
config-writePersist current theme and display settings to config
quitQuit

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.

KeyAction
j / ↓Next setting
k / ↑Previous setting
← / →Cycle value (theme, date format, week start)
Space / ← / →Toggle boolean (Obsidian enabled)
EnterOn text fields: start inline editing; on other rows: save and close
sSave and close
EscCancel (restores any live theme preview)

Settings covered

SettingDescription
ThemeCycles through all built-in and custom themes with live preview
Date formatYYYY-MM-DD HH:MM, DD-MM-YYYY HH:MM, or MM-DD-YYYY HH:MM
Week startFirst day of the week shown in the sidebar report
Obsidian enabledToggle Obsidian logging on/off
Vault directoryAbsolute path to your Obsidian vault
Activity categoryObsidian heading under which time entries are logged
Comment categoryObsidian 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 L key)
  • 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

KeyAction
↑ / ↓Select project
← / →Select task
EnterStart work session
BStart break (short or long)
SpacePause / Resume
LLog current session to database
RReset timer

Project & task management

KeyAction
PCreate new project
NCreate new task in selected project
EEdit selected project or task name
DDelete selected project or task (with confirmation)
CToggle selected task complete / reactivate
HHide / show completed tasks

Other

KeyAction
SOpen settings
Q / EscQuit (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 Enter to save
  • Press Esc to 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

KeyAction
↑ / ↓Navigate between settings
← / →Adjust value
EnterSave and return to main
EscCancel and discard changes

Timer Cycle & Notifications

Timer cycle

The timer follows this pattern (with default durations):

  1. Work session: 25 minutes (started with Enter)
  2. Short break: 5 minutes
  3. (repeat 3 more times)
  4. Long break: 15 minutes
  5. (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 pressing Space to 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 audio feature 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 audio feature, 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 = 0 to 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 Space to resume if paused.

Can’t open settings (tmkpr-pomodoro)

  • The settings screen is only available when the timer is stopped.
  • Press R to 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.