A minimalist, interactive command-line task manager built with Python.
Project description
odot
A minimalist, interactive command-line task manager built with Python.
odot provides a fast and intuitive way to manage your daily tasks directly from your terminal. Built upon Typer and SQLModel, it offers a robust SQLite-backed database with an elegant Terminal User Interface (TUI) for interactive task selection.
Features
- Interactive Prompts: Execute commands without remembering IDs. If you forget to pass an argument,
odotwill display a dynamic Arrow-Key navigable menu to select tasks. - Rich Output: Clean, formatted tables utilizing the
richlibrary for high readability. - Filtering: Easily filter missing or completed tasks right from the list command.
- Local First: Stores your data securely in a local
.sqlitedatabase configurable via environment variables. - Zero Configuration: Works out of the box with intelligent defaults.
Installation
You can install odot directly from PyPI using pip, pipx, or uv.
Using pip:
pip install odot
Using pipx (Recommended for isolated CLI application installations):
pipx install odot
Using uv:
uv tool install odot
Quick Start
Once installed, initialize the database to create the required tables on your local machine.
odot init-db
By default, the database is stored at ~/.odot/db.sqlite. You can override this by setting the ODOT_DB_PATH environment variable.
Usage
Adding a Task
You can add a task by passing the content directly, or you can supply priority (-p) and category (-c) flags.
odot add "Buy groceries for dinner"
odot add "Submit quarterly report" -p 3 -c work
Listing Tasks
View all of your current tasks in a formatted table.
odot list
You can optionally filter the list by status and category:
odot list --done # Show only completed tasks
odot list --todo # Show only open tasks
odot list --category work # Show only tasks in the 'work' category
odot list -c personal --todo # Show open tasks in the 'personal' category
You can also sort tasks by specific attributes (priority, date, category, status) and optionally reverse the sorting order:
odot list --sort priority # Sort by priority (ascending)
odot list --sort priority --reverse # Sort by priority (descending)
odot list --sort date # Sort by creation date
odot list --sort category -r # Sort by category (descending)
Searching Tasks
Find tasks whose content contains a specific phrase.
odot search "groceries"
odot search "quarterly report"
Showing a Task
View detailed properties and timestamps for a specific task. If you don't know the ID, simply run odot show without arguments to open the interactive selection menu.
odot show
odot show 1
Updating a Task
Update the properties of an existing task. If you run odot update without providing a task ID, it will gracefully open an interactive selection menu to pick a task. Subsequently, if you don't provide any explicit update flags, it will launch a multi-select interactive checklist allowing you to pick exactly which fields to change.
# Fully interactive mode (Prompts for task, then prompts for fields)
odot update
# Explicit mode
odot update 1 --content "Revised task name" --done --priority 2
Removing a Task
Delete a task from the database permanently. If you don't provide an ID, odot will open the interactive selection menu so you can browse for the task to delete. By default, odot prompts you for confirmation before execution unless you provide the --force flag.
# Interactive task selection mapping
odot rm
odot rm 1
odot rm 1 --force
Exporting and Importing Tasks
You can natively export your tasks as a JSON payload, or import them directly tracking native mappings conditionally. The export command dynamically evaluates filters natively identical to odot list, returning exactly matching subsets uniquely. When you want to preview the payload without saving to a file, omitting the path arguments effectively routes the output to standard out securely conditionally securely natively.
When invoking odot import, by default, imported JSON items are appended to your active configuration safely. Utilizing the --clear flag purges the existing active tasks conditionally allowing importing exact subsets seamlessly without overlaps natively.
# Export all open tasks explicitly conditionally
odot export backup.json --todo
# Conditionally output beautifully tracking the whole file explicitly visually validating
odot export --pretty
# Bulk import append matching fields safely extending implicitly natively securely elegantly selectively seamlessly conditionally
odot import backup.json
# Conditionally clear active records wrapping exception safely handling execution dynamically executing conditionally
odot import backup.json --clear
Generating Reports (Markdown/HTML)
Generate human-readable reports of your tasks. odot report automatically detects the output format based on the file extension (.md or .html) and supports the same filtering and sorting flags as the list command.
# Generate a Markdown report of all tasks sorted by priority
odot report tasks.md --sort priority
# Generate an HTML report of only open tasks in the 'work' category
odot report work_pending.html --todo --category work
Cleaning Completed Tasks
Delete all tasks currently marked as 'Done' from the database in bulk. Because this drops data, odot prompts for confirmation unless you use the --force flag.
odot clean # Prompts for confirmation
odot clean --force # Skip confirmation
Purging All Tasks
Delete all tasks from the database entirely, resetting your task list. Because this is a destructive action, odot will display a warning and ask for explicit confirmation unless you use the --force flag.
odot purge # Prompts for confirmation with a warning
odot purge --force # Skip confirmation
Development
If you wish to contribute or modify odot locally, ensure you have uv (for Python dependency management), gh (the GitHub CLI, for workflow automation), and just (the recipe task runner) installed.
- Clone the repository.
- Run
uv syncto install dependencies. - Authenticate the GitHub CLI via
gh auth login. - Use the included
justworkflows to run checks and tests:
just test # Run the pytest suite natively
just test-cov # Run tests and enforce 100% coverage
just check # Run Ruff formatting, linting, ty typechecks, and test loops
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file odot-0.2.0.tar.gz.
File metadata
- Download URL: odot-0.2.0.tar.gz
- Upload date:
- Size: 10.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
17edee77a526afd168e7bc28e2c1706d96ae9415dd86dee3b132c5ec96a5c17f
|
|
| MD5 |
77977c26725bc909808fc86f0a5e7194
|
|
| BLAKE2b-256 |
4c1a7a901ae1239b67bae559c8a3f0cf137d8a90c9dc8db9b688e5d94026b81c
|
Provenance
The following attestation bundles were made for odot-0.2.0.tar.gz:
Publisher:
release.yml on jkomalley/odot
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
odot-0.2.0.tar.gz -
Subject digest:
17edee77a526afd168e7bc28e2c1706d96ae9415dd86dee3b132c5ec96a5c17f - Sigstore transparency entry: 1047235934
- Sigstore integration time:
-
Permalink:
jkomalley/odot@d0f417234beb5ab87f3f4664c2014d398b4dca53 -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/jkomalley
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@d0f417234beb5ab87f3f4664c2014d398b4dca53 -
Trigger Event:
push
-
Statement type:
File details
Details for the file odot-0.2.0-py3-none-any.whl.
File metadata
- Download URL: odot-0.2.0-py3-none-any.whl
- Upload date:
- Size: 12.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9afcdf61b7a24bc5612744666357805aece15830a49c63250755c2192e250488
|
|
| MD5 |
de9ba554562c74b315444b789620c1f9
|
|
| BLAKE2b-256 |
f9f25af789f52c72055b1a5fa8fe7f34d4c480e680f94f72f53e43baf19776b3
|
Provenance
The following attestation bundles were made for odot-0.2.0-py3-none-any.whl:
Publisher:
release.yml on jkomalley/odot
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
odot-0.2.0-py3-none-any.whl -
Subject digest:
9afcdf61b7a24bc5612744666357805aece15830a49c63250755c2192e250488 - Sigstore transparency entry: 1047236002
- Sigstore integration time:
-
Permalink:
jkomalley/odot@d0f417234beb5ab87f3f4664c2014d398b4dca53 -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/jkomalley
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@d0f417234beb5ab87f3f4664c2014d398b4dca53 -
Trigger Event:
push
-
Statement type: