Git-backed markdown authorative todos with a local sqlite for indexes and queries.
  • Go 97.6%
  • Just 2.4%
Find a file
Viktor Varland 8a98ccea8f
All checks were successful
ci/woodpecker/push/build Pipeline was successful
ci/woodpecker/tag/release Pipeline was successful
docs: changelog for v1.2.2
2026-08-28 17:43:40 +02:00
.just feat: install to the XDG bin dir 2026-08-01 23:42:51 +02:00
.woodpecker ci: update to wrangle owned 2026-08-17 22:44:30 +02:00
internal fix: correct module path to git.meatbag.se/varl/todo 2026-06-25 09:28:40 +02:00
.gitignore chore: ignore local agent settings 2026-08-01 23:55:36 +02:00
CHANGELOG.md docs: changelog for v1.2.2 2026-08-28 17:43:40 +02:00
go.mod feat: add shell completion command 2026-06-25 11:43:19 +02:00
go.sum feat: add shell completion command 2026-06-25 11:43:19 +02:00
justfile feat: install to the XDG bin dir 2026-08-01 23:42:51 +02:00
main.go fix: honour XDG_DATA_HOME for the database and notes 2026-08-28 16:32:55 +02:00
main_test.go fix: honour XDG_DATA_HOME for the database and notes 2026-08-28 16:32:55 +02:00
README.md feat: add revamp 2026-02-27 20:33:57 +01:00

todo

Minimal sqlite-backed task manager with local markdown notes.

Usage

todo add "follow up with payroll"
todo edit 1
todo list
todo search "payroll"
todo done 1
todo show 1
todo import
todo import git@github.com:you/plan.git
todo export
todo sync /path/to/todo-notes

Storage

  • Database: ~/.local/share/todo/todo.db
  • Notes repo: ~/.local/share/todo/notes (sparse checkout of tasks/)
  • Tasks path: ~/.local/share/todo/notes/tasks/<uid>-<slug>.md

Notes are the source of truth. Each note includes metadata lines:

  • Status: open|done
  • Created: <RFC3339>
  • Updated: <RFC3339>
  • Completed: <RFC3339> (only when done)

Import expects notes named like <uid>-<slug>.md (slug = lowercase, 20 chars max). Each task has a stable uid used for filenames and cross-machine sync. Local numeric IDs are per-machine shortcuts.

Override paths with --db and --notes (repo root).

Commands

  • add [--edit] TITLE... add a task and optionally open the note
  • edit ID|UID open the task note in $EDITOR
  • list [--all] [--limit N] list tasks
  • search [--all] QUERY... search task titles
  • show ID|UID show details
  • done ID|UID mark a task done
  • import [GIT_URL] import notes into sqlite, optionally cloning into the notes repo first
  • export [--all] export sqlite tasks to notes
  • sync [DIR] [--all] export to DIR, git pull/push, import back

sync stores DIR in sqlite and reuses it when omitted. Tasks live under tasks in the repo. The repo is kept in sparse mode with tasks/ checked out.